Skip to content

Commit

Permalink
Merge branch 'master' into dbft3.0-doublespeakers
Browse files Browse the repository at this point in the history
  • Loading branch information
vncoelho authored Jun 6, 2024
2 parents 5de748b + 2fa8f0c commit a2614a3
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ public ExecutionContext LoadContract(ContractState contract, ContractMethodDescr
});

// Call initialization
var init = contract.Manifest.Abi.GetMethod("_initialize", 0);
var init = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Initialize, ContractBasicMethod.InitializePCount);
if (init != null)
{
LoadContext(context.Clone(init.Offset));
Expand Down
122 changes: 122 additions & 0 deletions src/Neo/SmartContract/ContractBasicMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ContractBasicMethod.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.

namespace Neo.SmartContract
{
/// <summary>
/// This class provides a guideline for basic methods used in the Neo blockchain, offering
/// a generalized interaction mechanism for smart contract deployment, verification, updates, and destruction.
/// </summary>
public record ContractBasicMethod
{
/// <summary>
/// The verification method. This must be called when withdrawing tokens from the contract.
/// If the contract address is included in the transaction signature, this method verifies the signature.
/// Example:
/// <code>
/// public static bool Verify() => Runtime.CheckWitness(Owner);
/// </code>
/// <code>
/// {
/// "name": "verify",
/// "safe": false,
/// "parameters": [],
/// "returntype": "bool"
/// }
/// </code>
/// </summary>
public static string Verify { get; } = "verify";

/// <summary>
/// The initialization method. Compiled into the <see cref="Manifest"/> file if any function uses the initialize statement.
/// These functions are executed first when loading the contract.
/// Example:
/// <code>
/// private static readonly UInt160 owner = "NdUL5oDPD159KeFpD5A9zw5xNF1xLX6nLT";
/// </code>
/// </summary>
public static string Initialize { get; } = "_initialize";

/// <summary>
/// The deployment method. Automatically executed by the ContractManagement contract when a contract is first deployed or updated.
/// <code>
/// {
/// "name": "_deploy",
/// "safe": false,
/// "parameters": [
/// {
/// "name": "data",
/// "type": "Any"
/// },
/// {
/// "name": "update",
/// "type": "Boolean"
/// }
/// ],
/// "returntype": "Void"
/// }
/// </code>
/// </summary>
public static string Deploy { get; } = "_deploy";

/// <summary>
/// The update method. Requires <see cref="NefFile"/> or <see cref="Manifest"/>, or both, and is passed to _deploy.
/// Should verify the signer's address using SYSCALL <code>Neo.Runtime.CheckWitness</code>.
/// <code>
/// {
/// "name": "update",
/// "safe": false,
/// "parameters": [
/// {
/// "name": "nefFile",
/// "type": "ByteArray"
/// },
/// {
/// "name": "manifest",
/// "type": "ByteArray"
/// },
/// {
/// "name": "data",
/// "type": "Any"
/// }
/// ],
/// "returntype": "Void"
/// }
/// </code>
/// </summary>
public static string Update { get; } = "update";

/// <summary>
/// The destruction method. Deletes all the storage of the contract.
/// Should verify the signer's address using SYSCALL <code>Neo.Runtime.CheckWitness</code>.
/// Any tokens in the contract must be transferred before destruction.
/// <code>
/// {
/// "name": "destroy",
/// "safe": false,
/// "parameters": [],
/// "returntype": "Void"
/// }
/// </code>
/// </summary>
public static string Destroy { get; } = "destroy";

/// <summary>
/// Parameter counts for the methods.
/// -1 represents the method can take arbitrary parameters.
/// </summary>
public static int VerifyPCount { get; } = -1;
public static int InitializePCount { get; } = 0;
public static int DeployPCount { get; } = 2;
public static int UpdatePCount { get; } = 3;
public static int DestroyPCount { get; } = 0;
}
}
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/DeployedContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public DeployedContract(ContractState contract)

Script = null;
ScriptHash = contract.Hash;
ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod("verify", -1);
ContractMethodDescriptor descriptor = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (descriptor is null) throw new NotSupportedException("The smart contract haven't got verify method.");

ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray();
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings
{
ContractState cs = NativeContract.ContractManagement.GetContract(snapshot, hash);
if (cs is null) return false;
ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify", -1);
ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (md?.ReturnType != ContractParameterType.Boolean) return false;
engine.LoadContract(cs, md, CallFlags.ReadOnly);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/Native/ContractManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor

private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState contract, StackItem data, bool update)
{
ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy", 2);
ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount);
if (md is not null)
await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update);
engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() });
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/Wallets/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot,
var contract = NativeContract.ContractManagement.GetContract(snapshot, hash);
if (contract is null)
throw new ArgumentException($"The smart contract or address {hash} is not found");
var md = contract.Manifest.Abi.GetMethod("verify", -1);
var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
if (md is null)
throw new ArgumentException($"The smart contract {contract.Hash} haven't got verify method");
if (md.ReturnType != ContractParameterType.Boolean)
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/OracleService/OracleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req

var oracleContract = NativeContract.ContractManagement.GetContract(snapshot, NativeContract.Oracle.Hash);
var engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: settings);
ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod("verify", -1);
ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
engine.LoadContract(oracleContract, md, CallFlags.None);
if (engine.Execute() != VMState.HALT) return null;
tx.NetworkFee += engine.FeeConsumed;
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/RpcServer/RpcServer.Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar
{
using var snapshot = system.GetSnapshot();
var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash).NotNull_Or(RpcError.UnknownContract);
var md = contract.Manifest.Abi.GetMethod("verify", -1).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
(md.ReturnType == ContractParameterType.Boolean).True_Or(RpcErrorFactory.InvalidContractVerification("The verify method doesn't return boolean value."));
Transaction tx = new()
{
Expand Down

0 comments on commit a2614a3

Please sign in to comment.