diff --git a/src/Plugins/RpcServer/Result.cs b/src/Plugins/RpcServer/Result.cs
index 9c7ace227c..c76e15153b 100644
--- a/src/Plugins/RpcServer/Result.cs
+++ b/src/Plugins/RpcServer/Result.cs
@@ -23,7 +23,7 @@ public static class Result
/// The return type
/// The execution result
/// The Rpc exception
- public static T Ok_Or(this Func function, RpcError err, bool withData = false)
+ public static T Ok_Or(Func function, RpcError err, bool withData = false)
{
try
{
diff --git a/src/Plugins/RpcServer/RpcServer.SmartContract.cs b/src/Plugins/RpcServer/RpcServer.SmartContract.cs
index 473ae0cb5d..70edc4cedb 100644
--- a/src/Plugins/RpcServer/RpcServer.SmartContract.cs
+++ b/src/Plugins/RpcServer/RpcServer.SmartContract.cs
@@ -213,7 +213,7 @@ private static Witness[] WitnessesFromJson(JArray _params)
}
[RpcMethod]
- protected virtual JToken InvokeFunction(JArray _params)
+ protected internal virtual JToken InvokeFunction(JArray _params)
{
UInt160 script_hash = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash {nameof(script_hash)}"));
string operation = Result.Ok_Or(() => _params[1].AsString(), RpcError.InvalidParams);
@@ -231,7 +231,7 @@ protected virtual JToken InvokeFunction(JArray _params)
}
[RpcMethod]
- protected virtual JToken InvokeScript(JArray _params)
+ protected internal virtual JToken InvokeScript(JArray _params)
{
byte[] script = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()), RpcError.InvalidParams);
Signer[] signers = _params.Count >= 2 ? SignersFromJson((JArray)_params[1], system.Settings) : null;
@@ -241,7 +241,7 @@ protected virtual JToken InvokeScript(JArray _params)
}
[RpcMethod]
- protected virtual JToken TraverseIterator(JArray _params)
+ protected internal virtual JToken TraverseIterator(JArray _params)
{
settings.SessionEnabled.True_Or(RpcError.SessionsDisabled);
Guid sid = Result.Ok_Or(() => Guid.Parse(_params[0].GetString()), RpcError.InvalidParams.WithData($"Invalid session id {nameof(sid)}"));
@@ -262,7 +262,7 @@ protected virtual JToken TraverseIterator(JArray _params)
}
[RpcMethod]
- protected virtual JToken TerminateSession(JArray _params)
+ protected internal virtual JToken TerminateSession(JArray _params)
{
settings.SessionEnabled.True_Or(RpcError.SessionsDisabled);
Guid sid = Result.Ok_Or(() => Guid.Parse(_params[0].GetString()), RpcError.InvalidParams.WithData("Invalid session id"));
@@ -278,7 +278,7 @@ protected virtual JToken TerminateSession(JArray _params)
}
[RpcMethod]
- protected virtual JToken GetUnclaimedGas(JArray _params)
+ protected internal virtual JToken GetUnclaimedGas(JArray _params)
{
string address = Result.Ok_Or(() => _params[0].AsString(), RpcError.InvalidParams.WithData($"Invalid address {nameof(address)}"));
JObject json = new();
diff --git a/src/Plugins/RpcServer/RpcServer.Wallet.cs b/src/Plugins/RpcServer/RpcServer.Wallet.cs
index 155c56d91b..50f3c7a1e0 100644
--- a/src/Plugins/RpcServer/RpcServer.Wallet.cs
+++ b/src/Plugins/RpcServer/RpcServer.Wallet.cs
@@ -48,22 +48,36 @@ public override void Delete() { }
public override void Save() { }
}
- protected Wallet wallet;
+ protected internal Wallet wallet;
+ ///
+ /// Checks if a wallet is open and throws an error if not.
+ ///
private void CheckWallet()
{
wallet.NotNull_Or(RpcError.NoOpenedWallet);
}
+ ///
+ /// Closes the currently opened wallet.
+ ///
+ /// An empty array.
+ /// Returns true if the wallet was successfully closed.
[RpcMethod]
- protected virtual JToken CloseWallet(JArray _params)
+ protected internal virtual JToken CloseWallet(JArray _params)
{
wallet = null;
return true;
}
+ ///
+ /// Exports the private key of a specified address.
+ ///
+ /// An array containing the address as a string.
+ /// The exported private key as a string.
+ /// Thrown when no wallet is open or the address is invalid.
[RpcMethod]
- protected virtual JToken DumpPrivKey(JArray _params)
+ protected internal virtual JToken DumpPrivKey(JArray _params)
{
CheckWallet();
UInt160 scriptHash = AddressToScriptHash(_params[0].AsString(), system.Settings.AddressVersion);
@@ -71,8 +85,14 @@ protected virtual JToken DumpPrivKey(JArray _params)
return account.GetKey().Export();
}
+ ///
+ /// Creates a new address in the wallet.
+ ///
+ /// An empty array.
+ /// The newly created address as a string.
+ /// Thrown when no wallet is open.
[RpcMethod]
- protected virtual JToken GetNewAddress(JArray _params)
+ protected internal virtual JToken GetNewAddress(JArray _params)
{
CheckWallet();
WalletAccount account = wallet.CreateAccount();
@@ -81,8 +101,14 @@ protected virtual JToken GetNewAddress(JArray _params)
return account.Address;
}
+ ///
+ /// Gets the balance of a specified asset in the wallet.
+ ///
+ /// An array containing the asset ID as a string.
+ /// A JSON object containing the balance of the specified asset.
+ /// Thrown when no wallet is open or the asset ID is invalid.
[RpcMethod]
- protected virtual JToken GetWalletBalance(JArray _params)
+ protected internal virtual JToken GetWalletBalance(JArray _params)
{
CheckWallet();
UInt160 asset_id = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset id: {_params[0]}"));
@@ -91,8 +117,14 @@ protected virtual JToken GetWalletBalance(JArray _params)
return json;
}
+ ///
+ /// Gets the amount of unclaimed GAS in the wallet.
+ ///
+ /// An empty array.
+ /// The amount of unclaimed GAS as a string.
+ /// Thrown when no wallet is open.
[RpcMethod]
- protected virtual JToken GetWalletUnclaimedGas(JArray _params)
+ protected internal virtual JToken GetWalletUnclaimedGas(JArray _params)
{
CheckWallet();
// Datoshi is the smallest unit of GAS, 1 GAS = 10^8 Datoshi
@@ -106,8 +138,14 @@ protected virtual JToken GetWalletUnclaimedGas(JArray _params)
return datoshi.ToString();
}
+ ///
+ /// Imports a private key into the wallet.
+ ///
+ /// An array containing the private key as a string.
+ /// A JSON object containing information about the imported account.
+ /// Thrown when no wallet is open or the private key is invalid.
[RpcMethod]
- protected virtual JToken ImportPrivKey(JArray _params)
+ protected internal virtual JToken ImportPrivKey(JArray _params)
{
CheckWallet();
string privkey = _params[0].AsString();
@@ -123,10 +161,20 @@ protected virtual JToken ImportPrivKey(JArray _params)
};
}
+ ///
+ /// Calculates the network fee for a given transaction.
+ ///
+ /// An array containing the Base64-encoded serialized transaction.
+ /// A JSON object containing the calculated network fee.
+ /// Thrown when the input parameters are invalid or the transaction is malformed.
[RpcMethod]
- protected virtual JToken CalculateNetworkFee(JArray _params)
+ protected internal virtual JToken CalculateNetworkFee(JArray _params)
{
- var tx = Convert.FromBase64String(_params[0].AsString());
+ if (_params.Count == 0)
+ {
+ throw new RpcException(RpcError.InvalidParams.WithData("Params array is empty, need a raw transaction."));
+ }
+ var tx = Result.Ok_Or(() => Convert.FromBase64String(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid tx: {_params[0]}")); ;
JObject account = new();
var networkfee = Wallets.Helper.CalculateNetworkFee(
@@ -136,8 +184,14 @@ protected virtual JToken CalculateNetworkFee(JArray _params)
return account;
}
+ ///
+ /// Lists all addresses in the wallet.
+ ///
+ /// An empty array.
+ /// An array of JSON objects, each containing information about an address in the wallet.
+ /// Thrown when no wallet is open.
[RpcMethod]
- protected virtual JToken ListAddress(JArray _params)
+ protected internal virtual JToken ListAddress(JArray _params)
{
CheckWallet();
return wallet.GetAccounts().Select(p =>
@@ -151,16 +205,39 @@ protected virtual JToken ListAddress(JArray _params)
}).ToArray();
}
+ ///
+ /// Opens a wallet file.
+ ///
+ /// An array containing the wallet path and password.
+ /// Returns true if the wallet was successfully opened.
+ /// Thrown when the wallet file is not found, the wallet is not supported, or the password is invalid.
[RpcMethod]
- protected virtual JToken OpenWallet(JArray _params)
+ protected internal virtual JToken OpenWallet(JArray _params)
{
string path = _params[0].AsString();
string password = _params[1].AsString();
File.Exists(path).True_Or(RpcError.WalletNotFound);
- wallet = Wallet.Open(path, password, system.Settings).NotNull_Or(RpcError.WalletNotSupported);
+ try
+ {
+ wallet = Wallet.Open(path, password, system.Settings).NotNull_Or(RpcError.WalletNotSupported);
+ }
+ catch (NullReferenceException)
+ {
+ throw new RpcException(RpcError.WalletNotSupported);
+ }
+ catch (InvalidOperationException)
+ {
+ throw new RpcException(RpcError.WalletNotSupported.WithData("Invalid password."));
+ }
+
return true;
}
+ ///
+ /// Processes the result of an invocation with wallet for signing.
+ ///
+ /// The result object to process.
+ /// Optional signers for the transaction.
private void ProcessInvokeWithWallet(JObject result, Signer[] signers = null)
{
if (wallet == null || signers == null || signers.Length == 0) return;
@@ -189,8 +266,14 @@ private void ProcessInvokeWithWallet(JObject result, Signer[] signers = null)
}
}
+ ///
+ /// Transfers an asset from a specific address to another address.
+ ///
+ /// An array containing asset ID, from address, to address, amount, and optional signers.
+ /// The transaction details if successful, or the contract parameters if signatures are incomplete.
+ /// Thrown when no wallet is open, parameters are invalid, or there are insufficient funds.
[RpcMethod]
- protected virtual JToken SendFrom(JArray _params)
+ protected internal virtual JToken SendFrom(JArray _params)
{
CheckWallet();
UInt160 assetId = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset id: {_params[0]}"));
@@ -202,7 +285,7 @@ protected virtual JToken SendFrom(JArray _params)
(amount.Sign > 0).True_Or(RpcErrorFactory.InvalidParams("Amount can't be negative."));
Signer[] signers = _params.Count >= 5 ? ((JArray)_params[4]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString(), system.Settings.AddressVersion), Scopes = WitnessScope.CalledByEntry }).ToArray() : null;
- Transaction tx = wallet.MakeTransaction(snapshot, new[]
+ Transaction tx = Result.Ok_Or(() => wallet.MakeTransaction(snapshot, new[]
{
new TransferOutput
{
@@ -210,7 +293,7 @@ protected virtual JToken SendFrom(JArray _params)
Value = amount,
ScriptHash = to
}
- }, from, signers).NotNull_Or(RpcError.InsufficientFunds);
+ }, from, signers), RpcError.InvalidRequest.WithData("Can not process this request.")).NotNull_Or(RpcError.InsufficientFunds);
ContractParametersContext transContext = new(snapshot, tx, settings.Network);
wallet.Sign(transContext);
@@ -227,8 +310,37 @@ protected virtual JToken SendFrom(JArray _params)
return SignAndRelay(snapshot, tx);
}
+ ///
+ /// Transfers assets to multiple addresses.
+ ///
+ ///
+ /// An array containing the following elements:
+ /// [0] (optional): The address to send from as a string. If omitted, the assets will be sent from any address in the wallet.
+ /// [1]: An array of transfer objects, each containing:
+ /// - "asset": The asset ID (UInt160) as a string.
+ /// - "value": The amount to transfer as a string.
+ /// - "address": The recipient address as a string.
+ /// [2] (optional): An array of signers, each containing:
+ /// - The address of the signer as a string.
+ ///
+ ///
+ /// If the transaction is successfully created and all signatures are present:
+ /// Returns a JSON object representing the transaction.
+ /// If not all signatures are present:
+ /// Returns a JSON object representing the contract parameters that need to be signed.
+ ///
+ ///
+ /// Thrown when:
+ /// - No wallet is open.
+ /// - The 'to' parameter is invalid or empty.
+ /// - Any of the asset IDs are invalid.
+ /// - Any of the amounts are negative or invalid.
+ /// - Any of the addresses are invalid.
+ /// - There are insufficient funds for the transfer.
+ /// - The network fee exceeds the maximum allowed fee.
+ ///
[RpcMethod]
- protected virtual JToken SendMany(JArray _params)
+ protected internal virtual JToken SendMany(JArray _params)
{
CheckWallet();
int to_start = 0;
@@ -273,8 +385,14 @@ protected virtual JToken SendMany(JArray _params)
return SignAndRelay(snapshot, tx);
}
+ ///
+ /// Transfers an asset to a specific address.
+ ///
+ /// An array containing asset ID, to address, and amount.
+ /// The transaction details if successful, or the contract parameters if signatures are incomplete.
+ /// Thrown when no wallet is open, parameters are invalid, or there are insufficient funds.
[RpcMethod]
- protected virtual JToken SendToAddress(JArray _params)
+ protected internal virtual JToken SendToAddress(JArray _params)
{
CheckWallet();
UInt160 assetId = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid asset hash: {_params[0]}"));
@@ -308,8 +426,14 @@ protected virtual JToken SendToAddress(JArray _params)
return SignAndRelay(snapshot, tx);
}
+ ///
+ /// Cancels an unconfirmed transaction.
+ ///
+ /// An array containing the transaction ID to cancel, signers, and optional extra fee.
+ /// The details of the cancellation transaction.
+ /// Thrown when no wallet is open, the transaction is already confirmed, or there are insufficient funds for the cancellation fee.
[RpcMethod]
- protected virtual JToken CancelTransaction(JArray _params)
+ protected internal virtual JToken CancelTransaction(JArray _params)
{
CheckWallet();
var txid = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid txid: {_params[0]}"));
@@ -342,8 +466,14 @@ protected virtual JToken CancelTransaction(JArray _params)
return SignAndRelay(system.StoreView, tx);
}
+ ///
+ /// Invokes the verify method of a contract.
+ ///
+ /// An array containing the script hash, optional arguments, and optional signers and witnesses.
+ /// A JSON object containing the result of the verification.
+ /// Thrown when the script hash is invalid, the contract is not found, or the verification fails.
[RpcMethod]
- protected virtual JToken InvokeContractVerify(JArray _params)
+ protected internal virtual JToken InvokeContractVerify(JArray _params)
{
UInt160 script_hash = Result.Ok_Or(() => UInt160.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash: {_params[0]}"));
ContractParameter[] args = _params.Count >= 2 ? ((JArray)_params[1]).Select(p => ContractParameter.FromJson((JObject)p)).ToArray() : Array.Empty();
@@ -352,6 +482,14 @@ protected virtual JToken InvokeContractVerify(JArray _params)
return GetVerificationResult(script_hash, args, signers, witnesses);
}
+ ///
+ /// Gets the result of the contract verification.
+ ///
+ /// The script hash of the contract.
+ /// The contract parameters.
+ /// Optional signers for the verification.
+ /// Optional witnesses for the verification.
+ /// A JSON object containing the verification result.
private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signer[] signers = null, Witness[] witnesses = null)
{
using var snapshot = system.GetSnapshotCache();
@@ -396,6 +534,12 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar
return json;
}
+ ///
+ /// Signs and relays a transaction.
+ ///
+ /// The data snapshot.
+ /// The transaction to sign and relay.
+ /// A JSON object containing the transaction details.
private JObject SignAndRelay(DataCache snapshot, Transaction tx)
{
ContractParametersContext context = new(snapshot, tx, settings.Network);
@@ -412,6 +556,12 @@ private JObject SignAndRelay(DataCache snapshot, Transaction tx)
}
}
+ ///
+ /// Converts an address to a script hash.
+ ///
+ /// The address to convert.
+ /// The address version.
+ /// The script hash corresponding to the address.
internal static UInt160 AddressToScriptHash(string address, byte version)
{
if (UInt160.TryParse(address, out var scriptHash))
diff --git a/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs
new file mode 100644
index 0000000000..2db71ae570
--- /dev/null
+++ b/tests/Neo.Plugins.RpcServer.Tests/UT_RpcServer.Wallet.cs
@@ -0,0 +1,403 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// UT_RpcServer.Wallet.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 FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Neo.IO;
+using Neo.Json;
+using Neo.Network.P2P.Payloads;
+using Neo.SmartContract;
+using Neo.SmartContract.Native;
+using Neo.UnitTests;
+using Neo.UnitTests.Extensions;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace Neo.Plugins.RpcServer.Tests;
+
+partial class UT_RpcServer
+{
+ [TestMethod]
+ public void TestOpenWallet()
+ {
+ const string Path = "wallet.json";
+ const string Password = "123456";
+ File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}");
+ var paramsArray = new JArray(Path, Password);
+ var res = _rpcServer.OpenWallet(paramsArray);
+ Assert.IsTrue(res.AsBoolean());
+ Assert.IsNotNull(_rpcServer.wallet);
+ Assert.AreEqual(_rpcServer.wallet.GetAccounts().FirstOrDefault()!.Address, "NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv");
+ _rpcServer.CloseWallet([]);
+ File.Delete(Path);
+ Assert.IsNull(_rpcServer.wallet);
+ }
+
+ [TestMethod]
+ public void TestOpenInvalidWallet()
+ {
+ const string Path = "wallet.json";
+ const string Password = "password";
+ File.Delete(Path);
+ var paramsArray = new JArray(Path, Password);
+ var exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet");
+ Assert.AreEqual(RpcError.WalletNotFound.Code, exception.HResult);
+
+ File.WriteAllText(Path, "{}");
+ exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet");
+ File.Delete(Path);
+ Assert.AreEqual(RpcError.WalletNotSupported.Code, exception.HResult);
+ var result = _rpcServer.CloseWallet(new JArray());
+ Assert.IsTrue(result.AsBoolean());
+ Assert.IsNull(_rpcServer.wallet);
+
+ File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}");
+ exception = Assert.ThrowsException(() => _rpcServer.OpenWallet(paramsArray), "Should throw RpcException for unsupported wallet");
+ Assert.AreEqual(RpcError.WalletNotSupported.Code, exception.HResult);
+ Assert.AreEqual(exception.Message, "Wallet not supported - Invalid password.");
+ File.Delete(Path);
+ }
+
+ [TestMethod]
+ public void TestDumpPrivKey()
+ {
+ TestUtilOpenWallet();
+ var account = _rpcServer.wallet.GetAccounts().FirstOrDefault();
+ Assert.IsNotNull(account);
+ var privKey = account.GetKey().Export();
+ var address = account.Address;
+ var result = _rpcServer.DumpPrivKey(new JArray(address));
+ Assert.AreEqual(privKey, result.AsString());
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestGetNewAddress()
+ {
+ TestUtilOpenWallet();
+ var result = _rpcServer.GetNewAddress([]);
+ Assert.IsInstanceOfType(result, typeof(JString));
+ Assert.IsTrue(_rpcServer.wallet.GetAccounts().Any(a => a.Address == result.AsString()));
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestGetWalletBalance()
+ {
+ TestUtilOpenWallet();
+ var assetId = NativeContract.NEO.Hash;
+ var paramsArray = new JArray(assetId.ToString());
+ var result = _rpcServer.GetWalletBalance(paramsArray);
+ Assert.IsInstanceOfType(result, typeof(JObject));
+ var json = (JObject)result;
+ Assert.IsTrue(json.ContainsProperty("balance"));
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestGetWalletBalanceInvalidAsset()
+ {
+ TestUtilOpenWallet();
+ var assetId = UInt160.Zero;
+ var paramsArray = new JArray(assetId.ToString());
+ var result = _rpcServer.GetWalletBalance(paramsArray);
+ Assert.IsInstanceOfType(result, typeof(JObject));
+ var json = (JObject)result;
+ Assert.IsTrue(json.ContainsProperty("balance"));
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestGetWalletUnclaimedGas()
+ {
+ TestUtilOpenWallet();
+ var result = _rpcServer.GetWalletUnclaimedGas([]);
+ Assert.IsInstanceOfType(result, typeof(JString));
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestImportPrivKey()
+ {
+ TestUtilOpenWallet();
+ var privKey = _walletAccount.GetKey().Export();
+ var paramsArray = new JArray(privKey);
+ var result = _rpcServer.ImportPrivKey(paramsArray);
+ Assert.IsInstanceOfType(result, typeof(JObject));
+ var json = (JObject)result;
+ Assert.IsTrue(json.ContainsProperty("address"));
+ Assert.IsTrue(json.ContainsProperty("haskey"));
+ Assert.IsTrue(json.ContainsProperty("label"));
+ Assert.IsTrue(json.ContainsProperty("watchonly"));
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestImportPrivKeyNoWallet()
+ {
+ var privKey = _walletAccount.GetKey().Export();
+ var paramsArray = new JArray(privKey);
+ var exception = Assert.ThrowsException(() => _rpcServer.ImportPrivKey(paramsArray));
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestCalculateNetworkFee()
+ {
+ var snapshot = _neoSystem.GetSnapshot();
+ var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount);
+ var txBase64 = Convert.ToBase64String(tx.ToArray());
+ var paramsArray = new JArray(txBase64);
+ var result = _rpcServer.CalculateNetworkFee(paramsArray);
+ Assert.IsInstanceOfType(result, typeof(JObject));
+ var json = (JObject)result;
+ Assert.IsTrue(json.ContainsProperty("networkfee"));
+ }
+
+ [TestMethod]
+ public void TestCalculateNetworkFeeNoParam()
+ {
+ var exception = Assert.ThrowsException(() => _rpcServer.CalculateNetworkFee([]));
+ Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code);
+ }
+
+ [TestMethod]
+ public void TestListAddressNoWallet()
+ {
+ var exception = Assert.ThrowsException(() => _rpcServer.ListAddress([]));
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestListAddress()
+ {
+ TestUtilOpenWallet();
+ var result = _rpcServer.ListAddress([]);
+ Assert.IsInstanceOfType(result, typeof(JArray));
+ var json = (JArray)result;
+ Assert.IsTrue(json.Count > 0);
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestSendFromNoWallet()
+ {
+ var assetId = NativeContract.GAS.Hash;
+ var from = _walletAccount.Address;
+ var to = _walletAccount.Address;
+ var amount = "1";
+ var paramsArray = new JArray(assetId.ToString(), from, to, amount);
+ var exception = Assert.ThrowsException(() => _rpcServer.SendFrom(paramsArray), "Should throw RpcException for insufficient funds");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestSendFrom()
+ {
+ TestUtilOpenWallet();
+ var assetId = NativeContract.GAS.Hash;
+ var from = _walletAccount.Address;
+ var to = _walletAccount.Address;
+ var amount = "1";
+ var paramsArray = new JArray(assetId.ToString(), from, to, amount);
+ var exception = Assert.ThrowsException(() => _rpcServer.SendFrom(paramsArray));
+ Assert.AreEqual(exception.HResult, RpcError.InvalidRequest.Code);
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestSendMany()
+ {
+ var from = _walletAccount.Address;
+ var to = new JArray { new JObject { ["asset"] = NativeContract.GAS.Hash.ToString(), ["value"] = "1", ["address"] = _walletAccount.Address } };
+ var paramsArray = new JArray(from, to);
+ var exception = Assert.ThrowsException(() => _rpcServer.SendMany(paramsArray), "Should throw RpcException for insufficient funds");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestSendToAddress()
+ {
+ var assetId = NativeContract.GAS.Hash;
+ var to = _walletAccount.Address;
+ var amount = "1";
+ var paramsArray = new JArray(assetId.ToString(), to, amount);
+ var exception = Assert.ThrowsException(() => _rpcServer.SendToAddress(paramsArray), "Should throw RpcException for insufficient funds");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestCloseWallet_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var result = _rpcServer.CloseWallet(new JArray());
+ Assert.IsTrue(result.AsBoolean());
+ }
+
+ [TestMethod]
+ public void TestDumpPrivKey_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var exception = Assert.ThrowsException(() => _rpcServer.DumpPrivKey(new JArray(_walletAccount.Address)), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestGetNewAddress_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var exception = Assert.ThrowsException(() => _rpcServer.GetNewAddress(new JArray()), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestGetWalletBalance_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var exception = Assert.ThrowsException(() => _rpcServer.GetWalletBalance(new JArray(NativeContract.NEO.Hash.ToString())), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestGetWalletUnclaimedGas_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var exception = Assert.ThrowsException(() => _rpcServer.GetWalletUnclaimedGas(new JArray()), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestImportPrivKey_WhenWalletNotOpen()
+ {
+ _rpcServer.wallet = null;
+ var privKey = _walletAccount.GetKey().Export();
+ var exception = Assert.ThrowsException(() => _rpcServer.ImportPrivKey(new JArray(privKey)), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ }
+
+ [TestMethod]
+ public void TestCalculateNetworkFee_InvalidTransactionFormat()
+ {
+ var invalidTxBase64 = "invalid_base64";
+ var paramsArray = new JArray(invalidTxBase64);
+ var exception = Assert.ThrowsException(() => _rpcServer.CalculateNetworkFee(paramsArray), "Should throw RpcException for invalid transaction format");
+ Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code);
+ }
+
+ [TestMethod]
+ public void TestListAddress_WhenWalletNotOpen()
+ {
+ // Ensure the wallet is not open
+ _rpcServer.wallet = null;
+
+ // Attempt to call ListAddress and expect an RpcException
+ var exception = Assert.ThrowsException(() => _rpcServer.ListAddress(new JArray()));
+
+ // Verify the exception has the expected error code
+ Assert.AreEqual(RpcError.NoOpenedWallet.Code, exception.HResult);
+ }
+
+ [TestMethod]
+ public void TestCancelTransaction()
+ {
+ TestUtilOpenWallet();
+ var snapshot = _neoSystem.GetSnapshot();
+ var tx = TestUtils.CreateValidTx(snapshot, _wallet, _walletAccount);
+ snapshot.Commit();
+ var paramsArray = new JArray(tx.Hash.ToString(), new JArray(_walletAccount.Address));
+ var exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(paramsArray), "Should throw RpcException for non-existing transaction");
+
+ Assert.AreEqual(RpcError.InsufficientFunds.Code, exception.HResult);
+
+ // Test with invalid transaction id
+ var invalidParamsArray = new JArray("invalid_txid", new JArray(_walletAccount.Address));
+ exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(invalidParamsArray), "Should throw RpcException for invalid txid");
+ Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code);
+
+ // Test with no signer
+ invalidParamsArray = new JArray(tx.Hash.ToString());
+ exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(invalidParamsArray), "Should throw RpcException for invalid txid");
+ Assert.AreEqual(exception.HResult, RpcError.BadRequest.Code);
+
+ // Test with null wallet
+ _rpcServer.wallet = null;
+ exception = Assert.ThrowsException(() => _rpcServer.CancelTransaction(paramsArray), "Should throw RpcException for no opened wallet");
+ Assert.AreEqual(exception.HResult, RpcError.NoOpenedWallet.Code);
+ TestUtilCloseWallet();
+ }
+
+ [TestMethod]
+ public void TestInvokeContractVerify()
+ {
+ var scriptHash = UInt160.Parse("0x70cde1619e405cdef363ab66a1e8dce430d798d5");
+ var paramsArray = new JArray(scriptHash.ToString());
+ var exception = Assert.ThrowsException(() => _rpcServer.InvokeContractVerify(paramsArray), "Should throw RpcException for unknown contract");
+ Assert.AreEqual(exception.HResult, RpcError.UnknownContract.Code);
+ // Test with invalid script hash
+ var invalidParamsArray = new JArray("invalid_script_hash");
+ exception = Assert.ThrowsException(() => _rpcServer.InvokeContractVerify(invalidParamsArray), "Should throw RpcException for invalid script hash");
+ Assert.AreEqual(exception.HResult, RpcError.InvalidParams.Code);
+ }
+
+
+ private void TestUtilOpenWallet()
+ {
+ try
+ {
+ const string Path = "wallet.json";
+ const string Password = "123456";
+ File.WriteAllText(Path, "{\"name\":null,\"version\":\"1.0\",\"scrypt\":{\"n\":16384,\"r\":8,\"p\":8},\"accounts\":[{\"address\":\"NVizn8DiExdmnpTQfjiVY3dox8uXg3Vrxv\",\"label\":null,\"isDefault\":false,\"lock\":false,\"key\":\"6PYPMrsCJ3D4AXJCFWYT2WMSBGF7dLoaNipW14t4UFAkZw3Z9vQRQV1bEU\",\"contract\":{\"script\":\"DCEDaR\\u002BFVb8lOdiMZ/wCHLiI\\u002Bzuf17YuGFReFyHQhB80yMpBVuezJw==\",\"parameters\":[{\"name\":\"signature\",\"type\":\"Signature\"}],\"deployed\":false},\"extra\":null}],\"extra\":null}");
+ var paramsArray = new JArray(Path, Password);
+ _rpcServer.OpenWallet(paramsArray);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ private void TestUtilCloseWallet()
+ {
+ try
+ {
+ const string Path = "wallet.json";
+ _rpcServer.CloseWallet([]);
+ File.Delete(Path);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ private UInt160 TestUtilAddTestContract()
+ {
+ var state = TestUtils.GetContract();
+
+ var storageKey = new StorageKey
+ {
+ Id = state.Id,
+ Key = new byte[] { 0x01 }
+ };
+
+ var storageItem = new StorageItem
+ {
+ Value = new byte[] { 0x01, 0x02, 0x03, 0x04 }
+ };
+
+ var snapshot = _neoSystem.GetSnapshotCache();
+ snapshot.AddContract(state.Hash, state);
+ snapshot.Add(storageKey, storageItem);
+ snapshot.Commit();
+ return state.Hash;
+ }
+}
diff --git a/tests/Neo.UnitTests/TestUtils.Contract.cs b/tests/Neo.UnitTests/TestUtils.Contract.cs
new file mode 100644
index 0000000000..da3139561c
--- /dev/null
+++ b/tests/Neo.UnitTests/TestUtils.Contract.cs
@@ -0,0 +1,105 @@
+// Copyright (C) 2015-2024 The Neo Project.
+//
+// TestUtils.Contract.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;
+using Neo.SmartContract.Manifest;
+using System;
+using System.Linq;
+
+namespace Neo.UnitTests;
+
+partial class TestUtils
+{
+ public static ContractManifest CreateDefaultManifest()
+ {
+ return new ContractManifest
+ {
+ Name = "testManifest",
+ Groups = [],
+ SupportedStandards = [],
+ Abi = new ContractAbi
+ {
+ Events = [],
+ Methods =
+ [
+ new ContractMethodDescriptor
+ {
+ Name = "testMethod",
+ Parameters = [],
+ ReturnType = ContractParameterType.Void,
+ Offset = 0,
+ Safe = true
+ }
+ ]
+ },
+ Permissions = [ContractPermission.DefaultPermission],
+ Trusts = WildcardContainer.Create(),
+ Extra = null
+ };
+ }
+
+ public static ContractManifest CreateManifest(string method, ContractParameterType returnType, params ContractParameterType[] parameterTypes)
+ {
+ var manifest = CreateDefaultManifest();
+ manifest.Abi.Methods =
+ [
+ new ContractMethodDescriptor()
+ {
+ Name = method,
+ Parameters = parameterTypes.Select((p, i) => new ContractParameterDefinition
+ {
+ Name = $"p{i}",
+ Type = p
+ }).ToArray(),
+ ReturnType = returnType
+ }
+ ];
+ return manifest;
+ }
+
+ public static ContractState GetContract(string method = "test", int parametersCount = 0)
+ {
+ NefFile nef = new()
+ {
+ Compiler = "",
+ Source = "",
+ Tokens = [],
+ Script = new byte[] { 0x01, 0x01, 0x01, 0x01 }
+ };
+ nef.CheckSum = NefFile.ComputeChecksum(nef);
+ return new ContractState
+ {
+ Id = 0x43000000,
+ Nef = nef,
+ Hash = nef.Script.Span.ToScriptHash(),
+ Manifest = CreateManifest(method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray())
+ };
+ }
+
+ internal static ContractState GetContract(byte[] script, ContractManifest manifest = null)
+ {
+ NefFile nef = new()
+ {
+ Compiler = "",
+ Source = "",
+ Tokens = [],
+ Script = script
+ };
+ nef.CheckSum = NefFile.ComputeChecksum(nef);
+ return new ContractState
+ {
+ Id = 1,
+ Hash = script.ToScriptHash(),
+ Nef = nef,
+ Manifest = manifest ?? CreateDefaultManifest()
+ };
+ }
+}
diff --git a/tests/Neo.UnitTests/TestUtils.Transaction.cs b/tests/Neo.UnitTests/TestUtils.Transaction.cs
index f96ac8ec74..f6d6ebd4b5 100644
--- a/tests/Neo.UnitTests/TestUtils.Transaction.cs
+++ b/tests/Neo.UnitTests/TestUtils.Transaction.cs
@@ -11,6 +11,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Cryptography;
+using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
@@ -22,11 +23,112 @@
using System;
using System.IO;
using System.Linq;
+using System.Numerics;
namespace Neo.UnitTests;
public partial class TestUtils
{
+ public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, WalletAccount account)
+ {
+ return CreateValidTx(snapshot, wallet, account.ScriptHash, (uint)new Random().Next());
+ }
+
+ public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce)
+ {
+ var tx = wallet.MakeTransaction(snapshot, [
+ new TransferOutput
+ {
+ AssetId = NativeContract.GAS.Hash,
+ ScriptHash = account,
+ Value = new BigDecimal(BigInteger.One, 8)
+ }
+ ],
+ account);
+
+ tx.Nonce = nonce;
+ tx.Signers = [new Signer { Account = account, Scopes = WitnessScope.CalledByEntry }];
+ var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network);
+ Assert.IsNull(data.GetSignatures(tx.Sender));
+ Assert.IsTrue(wallet.Sign(data));
+ Assert.IsTrue(data.Completed);
+ Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count);
+
+ tx.Witnesses = data.GetWitnesses();
+ return tx;
+ }
+
+ public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce, UInt256[] conflicts)
+ {
+ var tx = wallet.MakeTransaction(snapshot, [
+ new TransferOutput
+ {
+ AssetId = NativeContract.GAS.Hash,
+ ScriptHash = account,
+ Value = new BigDecimal(BigInteger.One, 8)
+ }
+ ],
+ account);
+ tx.Attributes = conflicts.Select(conflict => new Conflicts { Hash = conflict }).ToArray();
+ tx.Nonce = nonce;
+ tx.Signers = [new Signer { Account = account, Scopes = WitnessScope.CalledByEntry }];
+ var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network);
+ Assert.IsNull(data.GetSignatures(tx.Sender));
+ Assert.IsTrue(wallet.Sign(data));
+ Assert.IsTrue(data.Completed);
+ Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count);
+ tx.Witnesses = data.GetWitnesses();
+ return tx;
+ }
+
+ public static Transaction CreateRandomHashTransaction()
+ {
+ var randomBytes = new byte[16];
+ TestRandom.NextBytes(randomBytes);
+ return new Transaction
+ {
+ Script = randomBytes,
+ Attributes = [],
+ Signers = [new Signer { Account = UInt160.Zero }],
+ Witnesses =
+ [
+ new Witness
+ {
+ InvocationScript = Array.Empty(),
+ VerificationScript = Array.Empty()
+ }
+ ]
+ };
+ }
+
+ public static Transaction GetTransaction(UInt160 sender)
+ {
+ return new Transaction
+ {
+ Script = new[] { (byte)OpCode.PUSH2 },
+ Attributes = [],
+ Signers =
+ [
+ new Signer
+ {
+ Account = sender,
+ Scopes = WitnessScope.CalledByEntry,
+ AllowedContracts = [],
+ AllowedGroups = [],
+ Rules = [],
+ }
+ ],
+ Witnesses =
+ [
+ new Witness
+ {
+ InvocationScript = Array.Empty(),
+ VerificationScript = Array.Empty()
+ }
+ ]
+ };
+ }
+
public static Transaction CreateInvalidTransaction(DataCache snapshot, NEP6Wallet wallet, WalletAccount account, InvalidTransactionType type, UInt256 conflict = null)
{
var rand = new Random();
diff --git a/tests/Neo.UnitTests/TestUtils.cs b/tests/Neo.UnitTests/TestUtils.cs
index c1694347a7..a9ad4d8ff7 100644
--- a/tests/Neo.UnitTests/TestUtils.cs
+++ b/tests/Neo.UnitTests/TestUtils.cs
@@ -48,53 +48,6 @@ public static UInt160 RandomUInt160()
return new UInt160(data);
}
- public static ContractManifest CreateDefaultManifest()
- {
- return new ContractManifest()
- {
- Name = "testManifest",
- Groups = new ContractGroup[0],
- SupportedStandards = Array.Empty(),
- Abi = new ContractAbi()
- {
- Events = new ContractEventDescriptor[0],
- Methods = new[]
- {
- new ContractMethodDescriptor
- {
- Name = "testMethod",
- Parameters = new ContractParameterDefinition[0],
- ReturnType = ContractParameterType.Void,
- Offset = 0,
- Safe = true
- }
- }
- },
- Permissions = new[] { ContractPermission.DefaultPermission },
- Trusts = WildcardContainer.Create(),
- Extra = null
- };
- }
-
- public static ContractManifest CreateManifest(string method, ContractParameterType returnType, params ContractParameterType[] parameterTypes)
- {
- ContractManifest manifest = CreateDefaultManifest();
- manifest.Abi.Methods = new ContractMethodDescriptor[]
- {
- new ContractMethodDescriptor()
- {
- Name = method,
- Parameters = parameterTypes.Select((p, i) => new ContractParameterDefinition
- {
- Name = $"p{i}",
- Type = p
- }).ToArray(),
- ReturnType = returnType
- }
- };
- return manifest;
- }
-
public static StorageKey CreateStorageKey(this NativeContract contract, byte prefix, ISerializable key = null)
{
var k = new KeyBuilder(contract.Id, prefix);
@@ -130,118 +83,6 @@ public static NEP6Wallet GenerateTestWallet(string password)
return new NEP6Wallet(null, password, TestProtocolSettings.Default, wallet);
}
- public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, WalletAccount account)
- {
- return CreateValidTx(snapshot, wallet, account.ScriptHash, (uint)new Random().Next());
- }
-
- public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce)
- {
- var tx = wallet.MakeTransaction(snapshot, [
- new TransferOutput
- {
- AssetId = NativeContract.GAS.Hash,
- ScriptHash = account,
- Value = new BigDecimal(BigInteger.One, 8)
- }
- ],
- account);
-
- tx.Nonce = nonce;
-
- var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network);
- Assert.IsNull(data.GetSignatures(tx.Sender));
- Assert.IsTrue(wallet.Sign(data));
- Assert.IsTrue(data.Completed);
- Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count());
-
- tx.Witnesses = data.GetWitnesses();
- return tx;
- }
-
- public static Transaction CreateValidTx(DataCache snapshot, NEP6Wallet wallet, UInt160 account, uint nonce, UInt256[] conflicts)
- {
- var tx = wallet.MakeTransaction(snapshot, [
- new TransferOutput
- {
- AssetId = NativeContract.GAS.Hash,
- ScriptHash = account,
- Value = new BigDecimal(BigInteger.One, 8)
- }
- ],
- account);
- tx.Attributes = conflicts.Select(conflict => new Conflicts { Hash = conflict }).ToArray();
- tx.Nonce = nonce;
-
- var data = new ContractParametersContext(snapshot, tx, TestProtocolSettings.Default.Network);
- Assert.IsNull(data.GetSignatures(tx.Sender));
- Assert.IsTrue(wallet.Sign(data));
- Assert.IsTrue(data.Completed);
- Assert.AreEqual(1, data.GetSignatures(tx.Sender).Count);
- tx.Witnesses = data.GetWitnesses();
- return tx;
- }
-
- public static Transaction GetTransaction(UInt160 sender)
- {
- return new Transaction
- {
- Script = new byte[] { (byte)OpCode.PUSH2 },
- Attributes = Array.Empty(),
- Signers = new[]{ new Signer()
- {
- Account = sender,
- Scopes = WitnessScope.CalledByEntry,
- AllowedContracts = Array.Empty(),
- AllowedGroups = Array.Empty(),
- Rules = Array.Empty(),
- } },
- Witnesses = new Witness[]{ new Witness
- {
- InvocationScript = Array.Empty(),
- VerificationScript = Array.Empty()
- } }
- };
- }
-
- public static ContractState GetContract(string method = "test", int parametersCount = 0)
- {
- NefFile nef = new()
- {
- Compiler = "",
- Source = "",
- Tokens = Array.Empty(),
- Script = new byte[] { 0x01, 0x01, 0x01, 0x01 }
- };
- nef.CheckSum = NefFile.ComputeChecksum(nef);
- return new ContractState
- {
- Id = 0x43000000,
- Nef = nef,
- Hash = nef.Script.Span.ToScriptHash(),
- Manifest = CreateManifest(method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray())
- };
- }
-
- internal static ContractState GetContract(byte[] script, ContractManifest manifest = null)
- {
- NefFile nef = new()
- {
- Compiler = "",
- Source = "",
- Tokens = Array.Empty(),
- Script = script
- };
- nef.CheckSum = NefFile.ComputeChecksum(nef);
- return new ContractState
- {
- Id = 1,
- Hash = script.ToScriptHash(),
- Nef = nef,
- Manifest = manifest ?? CreateDefaultManifest()
- };
- }
-
internal static StorageItem GetStorageItem(byte[] value)
{
return new StorageItem
@@ -268,26 +109,6 @@ public static void StorageItemAdd(DataCache snapshot, int id, byte[] keyValue, b
}, new StorageItem(value));
}
- public static Transaction CreateRandomHashTransaction()
- {
- var randomBytes = new byte[16];
- TestRandom.NextBytes(randomBytes);
- return new Transaction
- {
- Script = randomBytes,
- Attributes = Array.Empty(),
- Signers = new Signer[] { new Signer() { Account = UInt160.Zero } },
- Witnesses = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new byte[0]
- }
- }
- };
- }
-
public static void FillMemoryPool(DataCache snapshot, NeoSystem system, NEP6Wallet wallet, WalletAccount account)
{
for (int i = 0; i < system.Settings.MemoryPoolMaxTransactions; i++)