Skip to content

Commit fa31bf2

Browse files
committed
Add runtime parse helpers for UInt types
1 parent dc19ebd commit fa31bf2

File tree

12 files changed

+484
-20
lines changed

12 files changed

+484
-20
lines changed

docs/security/access-control-patterns.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ using Neo.SmartContract.Framework.Services;
3636
public class OwnerOnlyContract : SmartContract
3737
{
3838
// Define contract owner at deployment time
39-
private static readonly UInt160 OWNER = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
39+
private static readonly UInt160 OWNER = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
4040

4141
/// <summary>
4242
/// Modifier to ensure only owner can execute function
@@ -100,7 +100,7 @@ Control access through a maintained list of authorized addresses.
100100
[DisplayName("WhitelistContract")]
101101
public class WhitelistContract : SmartContract
102102
{
103-
private static readonly UInt160 OWNER = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
103+
private static readonly UInt160 OWNER = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
104104
private static readonly StorageMap Whitelist = new(Storage.CurrentContext, "whitelist");
105105

106106
/// <summary>
@@ -178,7 +178,7 @@ public class RBACContract : SmartContract
178178
private static readonly StorageMap RolePermissions = new(Storage.CurrentContext, "role_permissions");
179179

180180
// Contract owner
181-
private static readonly UInt160 OWNER = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
181+
private static readonly UInt160 OWNER = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
182182

183183
/// <summary>
184184
/// Initialize contract with default roles and permissions
@@ -615,7 +615,7 @@ Implement access control based on time constraints and schedules.
615615
[ContractDescription("Time-based access control patterns")]
616616
public class TimeBasedAccessContract : SmartContract
617617
{
618-
private static readonly UInt160 OWNER = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
618+
private static readonly UInt160 OWNER = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
619619
private static readonly StorageMap TimeWindows = new(Storage.CurrentContext, "time_windows");
620620
private static readonly StorageMap UserAccess = new(Storage.CurrentContext, "user_access");
621621

@@ -928,4 +928,4 @@ public class AccessControlTests : TestBase<RBACContract>
928928
}
929929
```
930930

931-
Access control is the foundation of smart contract security. Always implement multiple layers of protection, test thoroughly, and follow the principle of least privilege to maintain a secure contract ecosystem.
931+
Access control is the foundation of smart contract security. Always implement multiple layers of protection, test thoroughly, and follow the principle of least privilege to maintain a secure contract ecosystem.

docs/security/security-best-practices.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static bool ProcessUserData(UInt160 user, string data, BigInteger amount)
6161
[DisplayName("RoleBasedContract")]
6262
public class RoleBasedContract : SmartContract
6363
{
64-
private static readonly UInt160 OWNER = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
64+
private static readonly UInt160 OWNER = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
6565

6666
// Role definitions
6767
private const string ADMIN_ROLE = "admin";
@@ -110,6 +110,9 @@ public class RoleBasedContract : SmartContract
110110
}
111111
```
112112

113+
> **Note**
114+
> When a script hash originates from runtime data, convert the value with `UInt160.Parse` (or cast from a validated byte array) before you return it. This keeps return statements strongly typed and prevents the NC4032 ReturnValueTypeAnalyzer from flagging implicit string conversions.
115+
113116
### Multi-Signature Security
114117

115118
```csharp
@@ -524,4 +527,4 @@ public class SecurityTests : TestBase<MyContract>
524527
}
525528
```
526529

527-
This comprehensive security guide provides the foundation for developing secure Neo smart contracts. Remember that security is an ongoing process, and you should regularly review and update your security practices as the ecosystem evolves.
530+
This comprehensive security guide provides the foundation for developing secure Neo smart contracts. Remember that security is an ongoing process, and you should regularly review and update your security practices as the ecosystem evolves.

docs/security/security-testing.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,28 @@ public class SecurityTestPlan : TestBase<YourContract>
9797
public class SecurityTestAccounts
9898
{
9999
// Standard test accounts
100-
public static readonly UInt160 Owner = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash();
101-
public static readonly UInt160 ValidUser = "NXpRXq8e9gRaH5vVAEUkHQeXNHLZsUfz1G".ToScriptHash();
102-
public static readonly UInt160 Attacker = "NVqXCjKHHi9xetyDhpEP6KtqCq8fHaXprC".ToScriptHash();
103-
public static readonly UInt160 UnauthorizedUser = "Nb2CHYY4wTqPQv7hPYnKr6CjN4fEeX2vks".ToScriptHash();
100+
public static readonly UInt160 Owner = UInt160.Parse("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB");
101+
public static readonly UInt160 ValidUser = UInt160.Parse("NXpRXq8e9gRaH5vVAEUkHQeXNHLZsUfz1G");
102+
public static readonly UInt160 Attacker = UInt160.Parse("NVqXCjKHHi9xetyDhpEP6KtqCq8fHaXprC");
103+
public static readonly UInt160 UnauthorizedUser = UInt160.Parse("Nb2CHYY4wTqPQv7hPYnKr6CjN4fEeX2vks");
104104

105105
// Multi-sig test accounts
106106
public static readonly UInt160[] MultiSigSigners = new[]
107107
{
108-
"NZNovmGqaNZF6P4qFUCcHzPE6GFU1F8ueT".ToScriptHash(),
109-
"NeJSJ4YsH89g9XrEqwWM4yVMm8jYM4jHG9".ToScriptHash(),
110-
"NbMKdHpJJ5T6K7gLhW2V8R9Q3wX5M8nTpN".ToScriptHash()
108+
UInt160.Parse("NZNovmGqaNZF6P4qFUCcHzPE6GFU1F8ueT"),
109+
UInt160.Parse("NeJSJ4YsH89g9XrEqwWM4yVMm8jYM4jHG9"),
110+
UInt160.Parse("NbMKdHpJJ5T6K7gLhW2V8R9Q3wX5M8nTpN")
111111
};
112112

113113
// Specialized test accounts
114-
public static readonly UInt160 ContractCaller = "NYzKR3qP8BV5w2j8Q9VH6tXz5M7nXsY8Tp".ToScriptHash();
115-
public static readonly UInt160 TokenHolder = "NQ5gR8pT9VX3j2m7W6hJ8kY5z4nP9qX7Bp".ToScriptHash();
114+
public static readonly UInt160 ContractCaller = UInt160.Parse("NYzKR3qP8BV5w2j8Q9VH6tXz5M7nXsY8Tp");
115+
public static readonly UInt160 TokenHolder = UInt160.Parse("NQ5gR8pT9VX3j2m7W6hJ8kY5z4nP9qX7Bp");
116116
}
117117
```
118118

119+
> **Note**
120+
> The same `UInt160.Parse` helper is available inside contracts, so your tests can mimic the strongly typed returns enforced by analyzer NC4032.
121+
119122
## Unit Testing for Security
120123

121124
### Input Validation Testing
@@ -929,4 +932,4 @@ public class SecurityTestReport
929932
}
930933
```
931934

932-
Security testing is an ongoing process that should be integrated throughout the development lifecycle. Regular testing, automated scans, and comprehensive reporting ensure that your Neo smart contracts maintain high security standards and protect user assets effectively.
935+
Security testing is an ongoing process that should be integrated throughout the development lifecycle. Regular testing, automated scans, and comprehensive reporting ensure that your Neo smart contracts maintain high security standards and protect user assets effectively.

src/Neo.SmartContract.Analyzer/ReturnValueTypeAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public sealed class ReturnValueTypeAnalyzer : DiagnosticAnalyzer
2424
private static readonly DiagnosticDescriptor Rule = new(
2525
DiagnosticId,
2626
"Return type must match declaration",
27-
"Return statements for '{0}' must return '{0}' values, but the expression has type '{1}'. Convert explicitly to '{0}'.",
27+
"Return statements for '{0}' must return '{0}' values, but the expression has type '{1}'. Convert explicitly to '{0}' (e.g., cast or parse the runtime value).",
2828
"Usage",
2929
DiagnosticSeverity.Error,
3030
isEnabledByDefault: true,

src/Neo.SmartContract.Framework/ECPoint.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ public extern bool IsValid
4242
[OpCode(OpCode.CONVERT, StackItemType.Buffer)]
4343
public static extern explicit operator byte[](ECPoint value);
4444

45+
[OpCode(OpCode.CONVERT, StackItemType.ByteString)]
46+
[OpCode(OpCode.DUP)]
47+
[OpCode(OpCode.ISNULL)]
48+
[OpCode(OpCode.JMPIF, "09")]
49+
[OpCode(OpCode.DUP)]
50+
[OpCode(OpCode.SIZE)]
51+
[OpCode(OpCode.PUSHINT8, "21")] // 0x21 == 33 bytes expected array size
52+
[OpCode(OpCode.JMPEQ, "03")]
53+
[OpCode(OpCode.THROW)]
54+
public static extern ECPoint Parse(string value);
55+
4556
/// <summary>
4657
/// Implicitly converts a hexadecimal string to a PublicKey object.
4758
/// Assumes the string is a valid hexadecimal representation.

src/Neo.SmartContract.Framework/UInt160.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ public extern bool IsValid
5656
[OpCode(OpCode.CONVERT, StackItemType.Buffer)]
5757
public static extern explicit operator byte[](UInt160 value);
5858

59+
[OpCode(OpCode.CONVERT, StackItemType.ByteString)]
60+
[OpCode(OpCode.DUP)]
61+
[OpCode(OpCode.ISNULL)]
62+
[OpCode(OpCode.JMPIF, "09")]
63+
[OpCode(OpCode.DUP)]
64+
[OpCode(OpCode.SIZE)]
65+
[OpCode(OpCode.PUSHINT8, "14")] // 0x14 == 20 bytes expected array size
66+
[OpCode(OpCode.JMPEQ, "03")]
67+
[OpCode(OpCode.THROW)]
68+
public static extern UInt160 Parse(string value);
69+
5970
/// <summary>
6071
/// Converts the specified script hash to an address, using the current blockchain AddressVersion value.
6172
/// </summary>

src/Neo.SmartContract.Framework/UInt256.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ public extern bool IsValid
5454
[OpCode(OpCode.CONVERT, StackItemType.Buffer)]
5555
public static extern explicit operator byte[](UInt256 value);
5656

57+
[OpCode(OpCode.CONVERT, StackItemType.ByteString)]
58+
[OpCode(OpCode.DUP)]
59+
[OpCode(OpCode.ISNULL)]
60+
[OpCode(OpCode.JMPIF, "09")]
61+
[OpCode(OpCode.DUP)]
62+
[OpCode(OpCode.SIZE)]
63+
[OpCode(OpCode.PUSHINT8, "20")] // 0x20 == 32 bytes expected array size
64+
[OpCode(OpCode.JMPEQ, "03")]
65+
[OpCode(OpCode.THROW)]
66+
public static extern UInt256 Parse(string value);
67+
5768
/// <summary>
5869
/// Implicitly converts a hexadecimal string to a UInt256 object.
5970
/// Assumes the string is a valid hexadecimal representation.

tests/Neo.SmartContract.Analyzer.UnitTests/ReturnValueTypeAnalyzerUnitTests.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ public abstract class UInt160
2727
{
2828
public static extern implicit operator UInt160(string value);
2929
public static extern explicit operator UInt160(byte[] value);
30+
public static UInt160 Parse(string value) => throw null!;
3031
}
3132
public abstract class UInt256
3233
{
3334
public static extern implicit operator UInt256(string value);
35+
public static UInt256 Parse(string value) => throw null!;
3436
}
3537
public abstract class ECPoint
3638
{
3739
public static extern implicit operator ECPoint(string value);
40+
public static ECPoint Parse(string value) => throw null!;
3841
}
3942
}
4043
""";
@@ -143,6 +146,42 @@ public static UInt160 Owner()
143146
await VerifyCS.VerifyAnalyzerAsync(code);
144147
}
145148

149+
[TestMethod]
150+
public async Task UInt160Parse_AllowsReturn()
151+
{
152+
var code = WithFrameworkStub("""
153+
using Neo.SmartContract.Framework;
154+
155+
class Contract : SmartContract
156+
{
157+
public static UInt160 Owner(string input)
158+
{
159+
return UInt160.Parse(input);
160+
}
161+
}
162+
""");
163+
164+
await VerifyCS.VerifyAnalyzerAsync(code);
165+
}
166+
167+
[TestMethod]
168+
public async Task UInt256Parse_AllowsReturn()
169+
{
170+
var code = WithFrameworkStub("""
171+
using Neo.SmartContract.Framework;
172+
173+
class Contract : SmartContract
174+
{
175+
public static UInt256 Hash(string input)
176+
{
177+
return UInt256.Parse(input);
178+
}
179+
}
180+
""");
181+
182+
await VerifyCS.VerifyAnalyzerAsync(code);
183+
}
184+
146185
[TestMethod]
147186
public async Task ECPointReturnWithString_ReportsDiagnostic()
148187
{
@@ -181,6 +220,24 @@ public static UInt160 Owner()
181220
await VerifyCS.VerifyAnalyzerAsync(code);
182221
}
183222

223+
[TestMethod]
224+
public async Task ECPointParse_AllowsReturn()
225+
{
226+
var code = WithFrameworkStub("""
227+
using Neo.SmartContract.Framework;
228+
229+
class Contract : SmartContract
230+
{
231+
public static ECPoint PubKey(string input)
232+
{
233+
return ECPoint.Parse(input);
234+
}
235+
}
236+
""");
237+
238+
await VerifyCS.VerifyAnalyzerAsync(code);
239+
}
240+
184241
[TestMethod]
185242
public async Task NullReturn_DoesNotReportDiagnostic()
186243
{

tests/Neo.SmartContract.Framework.TestContracts/Contract_UInt.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,20 @@ public static string ToAddress(UInt160 value)
2929
{
3030
return value.ToAddress();
3131
}
32+
33+
public static byte[] ParseUInt160Bytes(byte[] value)
34+
{
35+
return (byte[])UInt160.Parse((string)(ByteString)value);
36+
}
37+
38+
public static byte[] ParseUInt256Bytes(byte[] value)
39+
{
40+
return (byte[])UInt256.Parse((string)(ByteString)value);
41+
}
42+
43+
public static byte[] ParseECPointBytes(byte[] value)
44+
{
45+
return (byte[])ECPoint.Parse((string)(ByteString)value);
46+
}
3247
}
3348
}

tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_UInt.cs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public abstract class Contract_UInt(Neo.SmartContract.Testing.SmartContractIniti
1111
{
1212
#region Compiled data
1313

14-
public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_UInt"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""isValidAndNotZeroUInt256"",""parameters"":[{""name"":""value"",""type"":""Hash256""}],""returntype"":""Boolean"",""offset"":0,""safe"":false},{""name"":""isValidAndNotZeroUInt160"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":31,""safe"":false},{""name"":""isZeroUInt256"",""parameters"":[{""name"":""value"",""type"":""Hash256""}],""returntype"":""Boolean"",""offset"":62,""safe"":false},{""name"":""isZeroUInt160"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":69,""safe"":false},{""name"":""toAddress"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""String"",""offset"":76,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""base58CheckEncode""]}],""trusts"":[],""extra"":{""Version"":""3.8.1"",""nef"":{""optimization"":""All""}}}");
14+
public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_UInt"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""isValidAndNotZeroUInt256"",""parameters"":[{""name"":""value"",""type"":""Hash256""}],""returntype"":""Boolean"",""offset"":0,""safe"":false},{""name"":""isValidAndNotZeroUInt160"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":31,""safe"":false},{""name"":""isZeroUInt256"",""parameters"":[{""name"":""value"",""type"":""Hash256""}],""returntype"":""Boolean"",""offset"":62,""safe"":false},{""name"":""isZeroUInt160"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""Boolean"",""offset"":69,""safe"":false},{""name"":""toAddress"",""parameters"":[{""name"":""value"",""type"":""Hash160""}],""returntype"":""String"",""offset"":76,""safe"":false},{""name"":""parseUInt160Bytes"",""parameters"":[{""name"":""value"",""type"":""ByteArray""}],""returntype"":""ByteArray"",""offset"":116,""safe"":false},{""name"":""parseUInt256Bytes"",""parameters"":[{""name"":""value"",""type"":""ByteArray""}],""returntype"":""ByteArray"",""offset"":138,""safe"":false},{""name"":""parseECPointBytes"",""parameters"":[{""name"":""value"",""type"":""ByteArray""}],""returntype"":""ByteArray"",""offset"":160,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""base58CheckEncode""]}],""trusts"":[],""extra"":{""Version"":""3.8.1"",""nef"":{""optimization"":""All""}}}");
1515

1616
/// <summary>
1717
/// Optimization: "All"
1818
/// </summary>
19-
public static Neo.SmartContract.NefFile Nef => Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrBFiYXNlNThDaGVja0VuY29kZQEAAQ8AAHRXAAF4NANAVwABeErZKCQGRQkiBsoAILMkBAlAeLFAVwABeDQDQFcAAXhK2SgkBkUJIgbKABSzJAQJQHixQFcAAXixqkBXAAF4sapAVwABeDQDQFcAAUFMSZLceDQDQFcBAhGIShB50HBoeItwaNsoNwAAQDJLNGU=").AsSerializable<Neo.SmartContract.NefFile>();
19+
public static Neo.SmartContract.NefFile Nef => Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrBFiYXNlNThDaGVja0VuY29kZQEAAQ8AALZXAAF4NANAVwABeErZKCQGRQkiBsoAILMkBAlAeLFAVwABeDQDQFcAAXhK2SgkBkUJIgbKABSzJAQJQHixQFcAAXixqkBXAAF4sapAVwABeDQDQFcAAUFMSZLceDQDQFcBAhGIShB50HBoeItwaNsoNwAAQFcAAXjbKNsoStgkCUrKABQoAzrbMEBXAAF42yjbKErYJAlKygAgKAM62zBAVwABeNso2yhK2CQJSsoAISgDOtswQEeUpiI=").AsSerializable<Neo.SmartContract.NefFile>();
2020

2121
#endregion
2222

@@ -76,6 +76,75 @@ public abstract class Contract_UInt(Neo.SmartContract.Testing.SmartContractIniti
7676
[DisplayName("isZeroUInt256")]
7777
public abstract bool? IsZeroUInt256(UInt256? value);
7878

79+
/// <summary>
80+
/// Unsafe method
81+
/// </summary>
82+
/// <remarks>
83+
/// Script: VwABeNso2yhK2CQJSsoAISgDOtswQA==
84+
/// INITSLOT 0001 [64 datoshi]
85+
/// LDARG0 [2 datoshi]
86+
/// CONVERT 28 'ByteString' [8192 datoshi]
87+
/// CONVERT 28 'ByteString' [8192 datoshi]
88+
/// DUP [2 datoshi]
89+
/// ISNULL [2 datoshi]
90+
/// JMPIF 09 [2 datoshi]
91+
/// DUP [2 datoshi]
92+
/// SIZE [4 datoshi]
93+
/// PUSHINT8 21 [1 datoshi]
94+
/// JMPEQ 03 [2 datoshi]
95+
/// THROW [512 datoshi]
96+
/// CONVERT 30 'Buffer' [8192 datoshi]
97+
/// RET [0 datoshi]
98+
/// </remarks>
99+
[DisplayName("parseECPointBytes")]
100+
public abstract byte[]? ParseECPointBytes(byte[]? value);
101+
102+
/// <summary>
103+
/// Unsafe method
104+
/// </summary>
105+
/// <remarks>
106+
/// Script: VwABeNso2yhK2CQJSsoAFCgDOtswQA==
107+
/// INITSLOT 0001 [64 datoshi]
108+
/// LDARG0 [2 datoshi]
109+
/// CONVERT 28 'ByteString' [8192 datoshi]
110+
/// CONVERT 28 'ByteString' [8192 datoshi]
111+
/// DUP [2 datoshi]
112+
/// ISNULL [2 datoshi]
113+
/// JMPIF 09 [2 datoshi]
114+
/// DUP [2 datoshi]
115+
/// SIZE [4 datoshi]
116+
/// PUSHINT8 14 [1 datoshi]
117+
/// JMPEQ 03 [2 datoshi]
118+
/// THROW [512 datoshi]
119+
/// CONVERT 30 'Buffer' [8192 datoshi]
120+
/// RET [0 datoshi]
121+
/// </remarks>
122+
[DisplayName("parseUInt160Bytes")]
123+
public abstract byte[]? ParseUInt160Bytes(byte[]? value);
124+
125+
/// <summary>
126+
/// Unsafe method
127+
/// </summary>
128+
/// <remarks>
129+
/// Script: VwABeNso2yhK2CQJSsoAICgDOtswQA==
130+
/// INITSLOT 0001 [64 datoshi]
131+
/// LDARG0 [2 datoshi]
132+
/// CONVERT 28 'ByteString' [8192 datoshi]
133+
/// CONVERT 28 'ByteString' [8192 datoshi]
134+
/// DUP [2 datoshi]
135+
/// ISNULL [2 datoshi]
136+
/// JMPIF 09 [2 datoshi]
137+
/// DUP [2 datoshi]
138+
/// SIZE [4 datoshi]
139+
/// PUSHINT8 20 [1 datoshi]
140+
/// JMPEQ 03 [2 datoshi]
141+
/// THROW [512 datoshi]
142+
/// CONVERT 30 'Buffer' [8192 datoshi]
143+
/// RET [0 datoshi]
144+
/// </remarks>
145+
[DisplayName("parseUInt256Bytes")]
146+
public abstract byte[]? ParseUInt256Bytes(byte[]? value);
147+
79148
/// <summary>
80149
/// Unsafe method
81150
/// </summary>

0 commit comments

Comments
 (0)