Skip to content

Commit 2fa8f0c

Browse files
authored
[Neo Core Style] define a class for the contractbasemethod (neo-project#3291)
* define a class for the contractbasemethod, avoid directly using method name string and int pcount everywhere. * add mising file
1 parent fd1edf0 commit 2fa8f0c

File tree

8 files changed

+129
-7
lines changed

8 files changed

+129
-7
lines changed

src/Neo/SmartContract/ApplicationEngine.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ public ExecutionContext LoadContract(ContractState contract, ContractMethodDescr
436436
});
437437

438438
// Call initialization
439-
var init = contract.Manifest.Abi.GetMethod("_initialize", 0);
439+
var init = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Initialize, ContractBasicMethod.InitializePCount);
440440
if (init != null)
441441
{
442442
LoadContext(context.Clone(init.Offset));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright (C) 2015-2024 The Neo Project.
2+
//
3+
// ContractBasicMethod.cs file belongs to the neo project and is free
4+
// software distributed under the MIT software license, see the
5+
// accompanying file LICENSE in the main directory of the
6+
// repository or http://www.opensource.org/licenses/mit-license.php
7+
// for more details.
8+
//
9+
// Redistribution and use in source and binary forms with or without
10+
// modifications are permitted.
11+
12+
namespace Neo.SmartContract
13+
{
14+
/// <summary>
15+
/// This class provides a guideline for basic methods used in the Neo blockchain, offering
16+
/// a generalized interaction mechanism for smart contract deployment, verification, updates, and destruction.
17+
/// </summary>
18+
public record ContractBasicMethod
19+
{
20+
/// <summary>
21+
/// The verification method. This must be called when withdrawing tokens from the contract.
22+
/// If the contract address is included in the transaction signature, this method verifies the signature.
23+
/// Example:
24+
/// <code>
25+
/// public static bool Verify() => Runtime.CheckWitness(Owner);
26+
/// </code>
27+
/// <code>
28+
/// {
29+
/// "name": "verify",
30+
/// "safe": false,
31+
/// "parameters": [],
32+
/// "returntype": "bool"
33+
/// }
34+
/// </code>
35+
/// </summary>
36+
public static string Verify { get; } = "verify";
37+
38+
/// <summary>
39+
/// The initialization method. Compiled into the <see cref="Manifest"/> file if any function uses the initialize statement.
40+
/// These functions are executed first when loading the contract.
41+
/// Example:
42+
/// <code>
43+
/// private static readonly UInt160 owner = "NdUL5oDPD159KeFpD5A9zw5xNF1xLX6nLT";
44+
/// </code>
45+
/// </summary>
46+
public static string Initialize { get; } = "_initialize";
47+
48+
/// <summary>
49+
/// The deployment method. Automatically executed by the ContractManagement contract when a contract is first deployed or updated.
50+
/// <code>
51+
/// {
52+
/// "name": "_deploy",
53+
/// "safe": false,
54+
/// "parameters": [
55+
/// {
56+
/// "name": "data",
57+
/// "type": "Any"
58+
/// },
59+
/// {
60+
/// "name": "update",
61+
/// "type": "Boolean"
62+
/// }
63+
/// ],
64+
/// "returntype": "Void"
65+
/// }
66+
/// </code>
67+
/// </summary>
68+
public static string Deploy { get; } = "_deploy";
69+
70+
/// <summary>
71+
/// The update method. Requires <see cref="NefFile"/> or <see cref="Manifest"/>, or both, and is passed to _deploy.
72+
/// Should verify the signer's address using SYSCALL <code>Neo.Runtime.CheckWitness</code>.
73+
/// <code>
74+
/// {
75+
/// "name": "update",
76+
/// "safe": false,
77+
/// "parameters": [
78+
/// {
79+
/// "name": "nefFile",
80+
/// "type": "ByteArray"
81+
/// },
82+
/// {
83+
/// "name": "manifest",
84+
/// "type": "ByteArray"
85+
/// },
86+
/// {
87+
/// "name": "data",
88+
/// "type": "Any"
89+
/// }
90+
/// ],
91+
/// "returntype": "Void"
92+
/// }
93+
/// </code>
94+
/// </summary>
95+
public static string Update { get; } = "update";
96+
97+
/// <summary>
98+
/// The destruction method. Deletes all the storage of the contract.
99+
/// Should verify the signer's address using SYSCALL <code>Neo.Runtime.CheckWitness</code>.
100+
/// Any tokens in the contract must be transferred before destruction.
101+
/// <code>
102+
/// {
103+
/// "name": "destroy",
104+
/// "safe": false,
105+
/// "parameters": [],
106+
/// "returntype": "Void"
107+
/// }
108+
/// </code>
109+
/// </summary>
110+
public static string Destroy { get; } = "destroy";
111+
112+
/// <summary>
113+
/// Parameter counts for the methods.
114+
/// -1 represents the method can take arbitrary parameters.
115+
/// </summary>
116+
public static int VerifyPCount { get; } = -1;
117+
public static int InitializePCount { get; } = 0;
118+
public static int DeployPCount { get; } = 2;
119+
public static int UpdatePCount { get; } = 3;
120+
public static int DestroyPCount { get; } = 0;
121+
}
122+
}

src/Neo/SmartContract/DeployedContract.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public DeployedContract(ContractState contract)
3232

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

3838
ParameterList = descriptor.Parameters.Select(u => u.Type).ToArray();

src/Neo/SmartContract/Helper.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ internal static bool VerifyWitness(this IVerifiable verifiable, ProtocolSettings
332332
{
333333
ContractState cs = NativeContract.ContractManagement.GetContract(snapshot, hash);
334334
if (cs is null) return false;
335-
ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod("verify", -1);
335+
ContractMethodDescriptor md = cs.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
336336
if (md?.ReturnType != ContractParameterType.Boolean) return false;
337337
engine.LoadContract(cs, md, CallFlags.ReadOnly);
338338
}

src/Neo/SmartContract/Native/ContractManagement.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ internal override ContractTask InitializeAsync(ApplicationEngine engine, Hardfor
6060

6161
private async ContractTask OnDeployAsync(ApplicationEngine engine, ContractState contract, StackItem data, bool update)
6262
{
63-
ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy", 2);
63+
ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Deploy, ContractBasicMethod.DeployPCount);
6464
if (md is not null)
6565
await engine.CallFromNativeContractAsync(Hash, contract.Hash, md.Name, data, update);
6666
engine.SendNotification(Hash, update ? "Update" : "Deploy", new VM.Types.Array(engine.ReferenceCounter) { contract.Hash.ToArray() });

src/Neo/Wallets/Helper.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public static long CalculateNetworkFee(this Transaction tx, DataCache snapshot,
120120
var contract = NativeContract.ContractManagement.GetContract(snapshot, hash);
121121
if (contract is null)
122122
throw new ArgumentException($"The smart contract or address {hash} is not found");
123-
var md = contract.Manifest.Abi.GetMethod("verify", -1);
123+
var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
124124
if (md is null)
125125
throw new ArgumentException($"The smart contract {contract.Hash} haven't got verify method");
126126
if (md.ReturnType != ContractParameterType.Boolean)

src/Plugins/OracleService/OracleService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ public static Transaction CreateResponseTx(DataCache snapshot, OracleRequest req
428428

429429
var oracleContract = NativeContract.ContractManagement.GetContract(snapshot, NativeContract.Oracle.Hash);
430430
var engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: settings);
431-
ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod("verify", -1);
431+
ContractMethodDescriptor md = oracleContract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount);
432432
engine.LoadContract(oracleContract, md, CallFlags.None);
433433
if (engine.Execute() != VMState.HALT) return null;
434434
tx.NetworkFee += engine.FeeConsumed;

src/Plugins/RpcServer/RpcServer.Wallet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] ar
356356
{
357357
using var snapshot = system.GetSnapshot();
358358
var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash).NotNull_Or(RpcError.UnknownContract);
359-
var md = contract.Manifest.Abi.GetMethod("verify", -1).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
359+
var md = contract.Manifest.Abi.GetMethod(ContractBasicMethod.Verify, ContractBasicMethod.VerifyPCount).NotNull_Or(RpcErrorFactory.InvalidContractVerification(contract.Hash));
360360
(md.ReturnType == ContractParameterType.Boolean).True_Or(RpcErrorFactory.InvalidContractVerification("The verify method doesn't return boolean value."));
361361
Transaction tx = new()
362362
{

0 commit comments

Comments
 (0)