Skip to content

Commit

Permalink
Added Signers for Invoking contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
cschuchardt88 committed Sep 1, 2024
1 parent 498fd37 commit 7d9786e
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/Neo.CLI/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"Active": false
},
"Storage": {
"Engine": "LevelDBStore",
"Engine": "MemoryStore",
"Path": "Data_LevelDB_{0}"
},
"P2P": {
Expand Down
7 changes: 4 additions & 3 deletions src/Plugins/RestServer/Controllers/v1/ContractsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Neo.Plugins.RestServer.Extensions;
using Neo.Plugins.RestServer.Helpers;
using Neo.Plugins.RestServer.Models;
using Neo.Plugins.RestServer.Models.Contract;
using Neo.Plugins.RestServer.Models.Error;
using Neo.SmartContract;
using Neo.SmartContract.Manifest;
Expand Down Expand Up @@ -187,7 +188,7 @@ public IActionResult GetContractNef(
/// </summary>
/// <param name="scriptHash" example="0xed7cc6f5f2dd842d384f254bc0c2d58fb69a4761">ScriptHash</param>
/// <param name="method" example="balanceOf">method name</param>
/// <param name="contractParameters">JArray of the contract parameters.</param>
/// <param name="invokeParameters">JArray of the contract parameters.</param>
/// <returns>Execution Engine object.</returns>
/// <response code="200">Successful</response>
/// <response code="400">An error occurred. See Response for details.</response>
Expand All @@ -199,7 +200,7 @@ public IActionResult InvokeContract(
[FromQuery(Name = "method")]
string method,
[FromBody]
ContractParameter[] contractParameters)
InvokeParams invokeParameters)
{
var contracts = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, scriptHash);
if (contracts == null)
Expand All @@ -208,7 +209,7 @@ public IActionResult InvokeContract(
throw new QueryParameterNotFoundException(nameof(method));
try
{
var engine = ScriptHelper.InvokeMethod(_neoSystem.Settings, _neoSystem.StoreView, contracts.Hash, method, contractParameters, out var script);
var engine = ScriptHelper.InvokeMethod(_neoSystem.Settings, _neoSystem.StoreView, contracts.Hash, method, invokeParameters.ContractParameters, invokeParameters.Signers, out var script);
return Ok(engine.ToModel());
}
catch (Exception ex)
Expand Down
12 changes: 6 additions & 6 deletions src/Plugins/RestServer/Controllers/v1/NodeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ namespace Neo.Plugins.RestServer.Controllers.v1
[ApiController]
public class NodeController : ControllerBase
{
private readonly LocalNode _neolocalnode;
private readonly NeoSystem _neosystem;
private readonly LocalNode _neoLocalNode;
private readonly NeoSystem _neoSystem;

public NodeController()
{
_neolocalnode = RestServerPlugin.LocalNode ?? throw new InvalidOperationException();
_neosystem = RestServerPlugin.NeoSystem ?? throw new InvalidOperationException();
_neoLocalNode = RestServerPlugin.LocalNode ?? throw new InvalidOperationException();
_neoSystem = RestServerPlugin.NeoSystem ?? throw new InvalidOperationException();
}

/// <summary>
Expand All @@ -49,7 +49,7 @@ public NodeController()
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(RemoteNodeModel[]))]
public IActionResult GetPeers()
{
var rNodes = _neolocalnode
var rNodes = _neoLocalNode
.GetRemoteNodes()
.OrderByDescending(o => o.LastBlockIndex)
.ToArray();
Expand Down Expand Up @@ -83,6 +83,6 @@ public IActionResult GetPlugins() =>
[HttpGet("settings", Name = "GetNodeProtocolSettings")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ProtocolSettingsModel))]
public IActionResult GetSettings() =>
Ok(_neosystem.Settings.ToModel());
Ok(_neoSystem.Settings.ToModel());
}
}
30 changes: 15 additions & 15 deletions src/Plugins/RestServer/Controllers/v1/TokensController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ namespace Neo.Plugins.RestServer.Controllers.v1
[ApiController]
public class TokensController : ControllerBase
{
private readonly NeoSystem _neosystem;
private readonly NeoSystem _neoSystem;

public TokensController()
{
_neosystem = RestServerPlugin.NeoSystem ?? throw new NodeNetworkException();
_neoSystem = RestServerPlugin.NeoSystem ?? throw new NodeNetworkException();
}

#region NEP-17
Expand All @@ -63,7 +63,7 @@ public IActionResult GetNEP17(
{
if (skip < 1 || take < 1 || take > RestServerSettings.Current.MaxPageSize)
throw new InvalidParameterRangeException();
var tokenList = NativeContract.ContractManagement.ListContracts(_neosystem.StoreView);
var tokenList = NativeContract.ContractManagement.ListContracts(_neoSystem.StoreView);
var vaildContracts = tokenList
.Where(ContractHelper.IsNep17Supported)
.OrderBy(o => o.Manifest.Name)
Expand All @@ -76,7 +76,7 @@ public IActionResult GetNEP17(
{
try
{
var token = new NEP17Token(_neosystem, contract.Hash);
var token = new NEP17Token(_neoSystem, contract.Hash);
listResults.Add(token.ToModel());
}
catch
Expand All @@ -100,7 +100,7 @@ public IActionResult GetNEP17Count()
{
return Ok(new CountModel()
{
Count = NativeContract.ContractManagement.ListContracts(_neosystem.StoreView).Count(ContractHelper.IsNep17Supported)
Count = NativeContract.ContractManagement.ListContracts(_neoSystem.StoreView).Count(ContractHelper.IsNep17Supported)
});
}

Expand All @@ -120,13 +120,13 @@ public IActionResult GetNEP17(
[FromRoute(Name = "address")]
UInt160 lookupAddressOrScripthash)
{
var contract = NativeContract.ContractManagement.GetContract(_neosystem.StoreView, tokenAddessOrScripthash) ??
var contract = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, tokenAddessOrScripthash) ??
throw new ContractNotFoundException(tokenAddessOrScripthash);
if (ContractHelper.IsNep17Supported(contract) == false)
throw new Nep17NotSupportedException(tokenAddessOrScripthash);
try
{
var token = new NEP17Token(_neosystem, tokenAddessOrScripthash);
var token = new NEP17Token(_neoSystem, tokenAddessOrScripthash);
return Ok(new TokenBalanceModel()
{
Name = token.Name,
Expand Down Expand Up @@ -167,7 +167,7 @@ public IActionResult GetNEP11(
{
if (skip < 1 || take < 1 || take > RestServerSettings.Current.MaxPageSize)
throw new InvalidParameterRangeException();
var tokenList = NativeContract.ContractManagement.ListContracts(_neosystem.StoreView);
var tokenList = NativeContract.ContractManagement.ListContracts(_neoSystem.StoreView);
var vaildContracts = tokenList
.Where(ContractHelper.IsNep11Supported)
.OrderBy(o => o.Manifest.Name)
Expand All @@ -180,7 +180,7 @@ public IActionResult GetNEP11(
{
try
{
var token = new NEP11Token(_neosystem, contract.Hash);
var token = new NEP11Token(_neoSystem, contract.Hash);
listResults.Add(token.ToModel());
}
catch
Expand All @@ -202,7 +202,7 @@ public IActionResult GetNEP11(
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CountModel))]
public IActionResult GetNEP11Count()
{
return Ok(new CountModel() { Count = NativeContract.ContractManagement.ListContracts(_neosystem.StoreView).Count(ContractHelper.IsNep11Supported) });
return Ok(new CountModel() { Count = NativeContract.ContractManagement.ListContracts(_neoSystem.StoreView).Count(ContractHelper.IsNep11Supported) });
}

/// <summary>
Expand All @@ -221,13 +221,13 @@ public IActionResult GetNEP11(
[FromRoute(Name = "address")]
UInt160 addressHash)
{
var contract = NativeContract.ContractManagement.GetContract(_neosystem.StoreView, sAddressHash) ??
var contract = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, sAddressHash) ??
throw new ContractNotFoundException(sAddressHash);
if (ContractHelper.IsNep11Supported(contract) == false)
throw new Nep11NotSupportedException(sAddressHash);
try
{
var token = new NEP11Token(_neosystem, sAddressHash);
var token = new NEP11Token(_neoSystem, sAddressHash);
return Ok(new TokenBalanceModel()
{
Name = token.Name,
Expand Down Expand Up @@ -259,7 +259,7 @@ public IActionResult GetBalances(
[FromRoute(Name = "address")]
UInt160 addressOrScripthash)
{
var tokenList = NativeContract.ContractManagement.ListContracts(_neosystem.StoreView);
var tokenList = NativeContract.ContractManagement.ListContracts(_neoSystem.StoreView);
var validContracts = tokenList
.Where(w => ContractHelper.IsNep17Supported(w) || ContractHelper.IsNep11Supported(w))
.OrderBy(o => o.Manifest.Name);
Expand All @@ -268,7 +268,7 @@ public IActionResult GetBalances(
{
try
{
var token = new NEP17Token(_neosystem, contract.Hash);
var token = new NEP17Token(_neoSystem, contract.Hash);
var balance = token.BalanceOf(addressOrScripthash).Value;
if (balance == 0)
continue;
Expand All @@ -282,7 +282,7 @@ public IActionResult GetBalances(
TotalSupply = token.TotalSupply().Value,
});

var nft = new NEP11Token(_neosystem, contract.Hash);
var nft = new NEP11Token(_neoSystem, contract.Hash);
balance = nft.BalanceOf(addressOrScripthash).Value;
if (balance == 0)
continue;
Expand Down
10 changes: 5 additions & 5 deletions src/Plugins/RestServer/Controllers/v1/UtilsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ namespace Neo.Plugins.RestServer.Controllers.v1
[ApiController]
public class UtilsController : ControllerBase
{
private readonly NeoSystem _neosystem;
private readonly NeoSystem _neoSystem;

public UtilsController()
{
_neosystem = RestServerPlugin.NeoSystem ?? throw new NodeNetworkException();
_neoSystem = RestServerPlugin.NeoSystem ?? throw new NodeNetworkException();
}

#region Validation
Expand All @@ -52,7 +52,7 @@ public IActionResult ScriptHashToWalletAddress(
{
try
{
return Ok(new UtilsAddressModel() { Address = ScriptHash.ToAddress(_neosystem.Settings.AddressVersion) });
return Ok(new UtilsAddressModel() { Address = ScriptHash.ToAddress(_neoSystem.Settings.AddressVersion) });
}
catch (FormatException)
{
Expand All @@ -75,7 +75,7 @@ public IActionResult WalletAddressToScriptHash(
{
try
{
return Ok(new UtilsScriptHashModel() { ScriptHash = address.ToScriptHash(_neosystem.Settings.AddressVersion) });
return Ok(new UtilsScriptHashModel() { ScriptHash = address.ToScriptHash(_neoSystem.Settings.AddressVersion) });
}
catch (FormatException)
{
Expand All @@ -99,7 +99,7 @@ public IActionResult ValidateAddress(
return Ok(new UtilsAddressIsValidModel()
{
Address = AddressOrScriptHash,
IsValid = RestServerUtility.TryConvertToScriptHash(AddressOrScriptHash, _neosystem.Settings, out _),
IsValid = RestServerUtility.TryConvertToScriptHash(AddressOrScriptHash, _neoSystem.Settings, out _),
});
}

Expand Down
15 changes: 13 additions & 2 deletions src/Plugins/RestServer/Helpers/ScriptHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Linq;

namespace Neo.Plugins.RestServer.Helpers
{
Expand All @@ -31,11 +32,21 @@ public static bool InvokeMethod(ProtocolSettings protocolSettings, DataCache sna
return engine.State == VMState.HALT;
}

public static ApplicationEngine InvokeMethod(ProtocolSettings protocolSettings, DataCache snapshot, UInt160 scriptHash, string method, ContractParameter[] args, out byte[] script)
public static ApplicationEngine InvokeMethod(ProtocolSettings protocolSettings, DataCache snapshot, UInt160 scriptHash, string method, ContractParameter[] args, Signer[]? signers, out byte[] script)
{
using var scriptBuilder = new ScriptBuilder();
scriptBuilder.EmitDynamicCall(scriptHash, method, CallFlags.ReadOnly, args);
script = scriptBuilder.ToArray();
var tx = signers == null ? null : new Transaction
{
Version = 0,
Nonce = (uint)Random.Shared.Next(),
ValidUntilBlock = NativeContract.Ledger.CurrentIndex(snapshot) + protocolSettings.MaxValidUntilBlockIncrement,
Signers = signers,
Attributes = [],
Script = script,
Witnesses = [.. signers.Select(s => new Witness())],
};
using var engine = ApplicationEngine.Run(script, snapshot, settings: protocolSettings, gas: RestServerSettings.Current.MaxGasInvoke);
return engine;
}
Expand All @@ -45,7 +56,7 @@ public static ApplicationEngine InvokeScript(ReadOnlyMemory<byte> script, Signer
var neoSystem = RestServerPlugin.NeoSystem ?? throw new InvalidOperationException();

var snapshot = neoSystem.GetSnapshotCache();
Transaction? tx = signers == null ? null : new Transaction
var tx = signers == null ? null : new Transaction
{
Version = 0,
Nonce = (uint)Random.Shared.Next(),
Expand Down
22 changes: 22 additions & 0 deletions src/Plugins/RestServer/Models/Contract/InvokeParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// InvokeParams.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.Network.P2P.Payloads;
using Neo.SmartContract;

namespace Neo.Plugins.RestServer.Models.Contract
{
public class InvokeParams
{
public ContractParameter[] ContractParameters { get; set; } = [];
public Signer[] Signers { get; set; } = [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ContractInvokeParametersJsonConverter.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.Plugins.RestServer.Models.Contract;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

namespace Neo.Plugins.RestServer.Newtonsoft.Json
{
public class ContractInvokeParametersJsonConverter : JsonConverter<InvokeParams>
{
public override bool CanRead => true;
public override bool CanWrite => false;

public override InvokeParams ReadJson(JsonReader reader, Type objectType, InvokeParams? existingValue, bool hasExistingValue, global::Newtonsoft.Json.JsonSerializer serializer)
{
var token = JToken.ReadFrom(reader);
return RestServerUtility.ContractInvokeParametersFromJToken(token);
}

public override void WriteJson(JsonWriter writer, InvokeParams? value, global::Newtonsoft.Json.JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
7 changes: 4 additions & 3 deletions src/Plugins/RestServer/RestServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,16 @@ public class RestServerSettings
MissingMemberHandling = MissingMemberHandling.Error,
NullValueHandling = NullValueHandling.Include,
Formatting = Formatting.None,
Converters = new JsonConverter[]
{
Converters =
[
new StringEnumConverter(),
new BigDecimalJsonConverter(),
new BlockHeaderJsonConverter(),
new BlockJsonConverter(),
new ContractAbiJsonConverter(),
new ContractEventDescriptorJsonConverter(),
new ContractGroupJsonConverter(),
new ContractInvokeParametersJsonConverter(),
new ContractJsonConverter(),
new ContractManifestJsonConverter(),
new ContractMethodJsonConverter(),
Expand Down Expand Up @@ -119,7 +120,7 @@ public class RestServerSettings
new WitnessConditionJsonConverter(),
new WitnessJsonConverter(),
new WitnessRuleJsonConverter(),
},
],
},
};

Expand Down
Loading

0 comments on commit 7d9786e

Please sign in to comment.