Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve parse method in neo-cli #3204

Merged
merged 30 commits into from
May 20, 2024
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e1d8e14
Update MainService.Tools.cs
chenzhitong Apr 24, 2024
25b16f6
format
chenzhitong Apr 24, 2024
0bcbcda
Update MainService.Tools.cs
chenzhitong Apr 24, 2024
0c36106
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
43faa79
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
4acbe95
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
ecc7cbb
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
9e6f07c
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
ff3406d
Update MainService.Tools.cs
chenzhitong Apr 26, 2024
214f62b
update
chenzhitong May 1, 2024
7b5c9e1
Update MainService.Tools.cs
chenzhitong May 1, 2024
7b9a17a
Update MainService.Tools.cs
chenzhitong May 6, 2024
75f4473
Merge branch 'master' into converter
chenzhitong May 6, 2024
b42fa7b
Update MainService.Tools.cs
chenzhitong May 6, 2024
7d5c5ca
Merge branch 'converter' of /~https://github.com/chenzhitong/neo into c…
chenzhitong May 6, 2024
31c226f
Merge branch 'master' into converter
chenzhitong May 7, 2024
90d10ef
format
chenzhitong May 7, 2024
010f34b
Merge branch 'master' into converter
chenzhitong May 9, 2024
cd69789
Merge branch 'master' into converter
chenzhitong May 10, 2024
819f1cf
Merge branch 'master' into converter
chenzhitong May 10, 2024
4fb2a2d
Update MainService.Tools.cs
chenzhitong May 10, 2024
fcc8cec
Merge branch 'master' into converter
cschuchardt88 May 10, 2024
484f1e6
Merge branch 'master' into converter
shargon May 13, 2024
250c8ea
Review
shargon May 13, 2024
6fdab35
fixedbug
chenzhitong May 14, 2024
17141e4
Update MainService.Tools.cs
chenzhitong May 14, 2024
63e992a
Merge branch 'master' into converter
shargon May 16, 2024
ef81c32
Merge branch 'master' into converter
Jim8y May 16, 2024
4f6afbb
Merge branch 'master' into converter
shargon May 20, 2024
f6e652e
Merge branch 'master' into converter
shargon May 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 47 additions & 84 deletions src/Neo.CLI/CLI/MainService.Tools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private void OnParseCommand(string value)
}
}

bool any = false;
var any = false;

foreach (var pair in parseFunctions)
{
Expand Down Expand Up @@ -96,7 +96,7 @@ private void OnParseCommand(string value)
{
try
{
bool hasHexPrefix = hex.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase);
var hasHexPrefix = hex.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase);
hex = hasHexPrefix ? hex[2..] : hex;
if (!hasHexPrefix || !IsHex(hex)) return null;
return hex.HexToBytes().Reverse().ToArray().ToHexString();
Expand All @@ -117,9 +117,8 @@ private void OnParseCommand(string value)
{
try
{
byte[] bytearray = Utility.StrictUTF8.GetBytes(strParam);
string base64 = Convert.ToBase64String(bytearray.AsSpan());
return base64;
var bytearray = Utility.StrictUTF8.GetBytes(strParam);
return Convert.ToBase64String(bytearray.AsSpan());
}
catch
{
Expand All @@ -141,18 +140,16 @@ private void OnParseCommand(string value)
{
return null;
}
byte[] bytearray = number.ToByteArray();
string base64 = Convert.ToBase64String(bytearray.AsSpan());

return base64;
var bytearray = number.ToByteArray();
return Convert.ToBase64String(bytearray.AsSpan());
}
catch
{
return null;
}
}

private bool IsHex(string str) => str.Length % 2 == 0 && str.All(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
private static bool IsHex(string str) => str.Length % 2 == 0 && str.All(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));

/// <summary>
/// Fix for Base64 strings containing unicode
Expand All @@ -161,7 +158,7 @@ private void OnParseCommand(string value)
/// </summary>
/// <param name="str">Base64 strings containing unicode</param>
/// <returns>Correct Base64 string</returns>
public string Base64Fixed(string str)
private static string Base64Fixed(string str)
{
var sb = new StringBuilder();
for (var i = 0; i < str.Length; i++)
Expand Down Expand Up @@ -201,7 +198,6 @@ public string Base64Fixed(string str)
try
{
var bigEndScript = address.ToScriptHash(NeoSystem.Settings.AddressVersion);

return bigEndScript.ToString();
}
catch
Expand All @@ -221,7 +217,6 @@ public string Base64Fixed(string str)
try
{
var bigEndScript = address.ToScriptHash(NeoSystem.Settings.AddressVersion);

return bigEndScript.ToArray().ToHexString();
}
catch
Expand All @@ -241,9 +236,7 @@ public string Base64Fixed(string str)
try
{
var script = address.ToScriptHash(NeoSystem.Settings.AddressVersion);
string base64 = Convert.ToBase64String(script.ToArray().AsSpan());

return base64;
return Convert.ToBase64String(script.ToArray().AsSpan());
}
catch
{
Expand Down Expand Up @@ -275,15 +268,14 @@ public string Base64Fixed(string str)
{
return null;
}
string bigEndScript = littleEndScript.ToArray().ToHexString();
var bigEndScript = littleEndScript.ToArray().ToHexString();
if (!UInt160.TryParse(bigEndScript, out scriptHash))
{
return null;
}
}

var hexScript = scriptHash.ToAddress(NeoSystem.Settings.AddressVersion);
return hexScript;
return scriptHash.ToAddress(NeoSystem.Settings.AddressVersion);
}
catch
{
Expand All @@ -301,16 +293,15 @@ public string Base64Fixed(string str)
{
try
{
byte[] result = Convert.FromBase64String(bytearray).Reverse().ToArray();
string hex = result.ToHexString();
var result = Convert.FromBase64String(bytearray).Reverse().ToArray();
var hex = result.ToHexString();

if (!UInt160.TryParse(hex, out var scripthash))
{
return null;
}

string address = scripthash.ToAddress(NeoSystem.Settings.AddressVersion);
return address;
return scripthash.ToAddress(NeoSystem.Settings.AddressVersion);
}
catch
{
Expand All @@ -328,8 +319,8 @@ public string Base64Fixed(string str)
{
try
{
byte[] result = Convert.FromBase64String(bytearray);
string utf8String = Utility.StrictUTF8.GetString(result);
var result = Convert.FromBase64String(bytearray);
var utf8String = Utility.StrictUTF8.GetString(result);
return IsPrintable(utf8String) ? utf8String : null;
}
catch
Expand Down Expand Up @@ -426,88 +417,60 @@ public string Base64Fixed(string str)
[ParseFunction("Base64 Smart Contract Script Analysis")]
private string? ScriptsToOpCode(string base64)
{
List<byte> scripts;
try
{
scripts = Convert.FromBase64String(base64).ToList();
}
catch (Exception)
{
return null;
}
Script script;
try
{
_ = new Script(scripts.ToArray(), true);
var scriptData = Convert.FromBase64String(base64);
script = new Script(scriptData.ToArray(), true);
}
catch (Exception)
{
return null;
}
return ScriptsToOpCode(scripts);
return ScriptsToOpCode(script);
}

private string ScriptsToOpCode(List<byte> scripts)
private string ScriptsToOpCode(Script script)
{
//Initialize all OpCodes
var OperandSizePrefixTable = new int[256];
var OperandSizeTable = new int[256];
foreach (FieldInfo field in typeof(OpCode).GetFields(BindingFlags.Public | BindingFlags.Static))
{
var attribute = field.GetCustomAttribute<OperandSizeAttribute>();
if (attribute == null) continue;
int index = (int)(OpCode)field.GetValue(null);
OperandSizePrefixTable[index] = attribute.SizePrefix;
OperandSizeTable[index] = attribute.Size;
}
//Initialize all InteropService
var dic = new Dictionary<uint, string>();
ApplicationEngine.Services.ToList().ForEach(p => dic.Add(p.Value.Hash, p.Value.Name));

//Analyzing Scripts
var ip = 0;
Instruction instruction;
var result = new List<string>();
while (scripts.Count > 0)
while ((instruction = script.GetInstruction(ip)) != null)
{
var op = (OpCode)scripts[0];
var operandSizePrefix = OperandSizePrefixTable[scripts[0]];
var operandSize = OperandSizeTable[scripts[0]];
scripts.RemoveAt(0);
ip += instruction.Size;
if (ip >= script.Length) break;

var op = instruction.OpCode;

var onlyOpCode = true;
if (operandSize > 0)
if (op.ToString().StartsWith("PUSHINT"))
{
var operand = scripts.Take(operandSize).ToArray();
if (op.ToString().StartsWith("PUSHINT"))
{
result.Add($"{op} {new BigInteger(operand)}");
}
else if (op == OpCode.SYSCALL)
var operand = instruction.Operand.ToArray();
result.Add($"{op} {new BigInteger(operand)}");
}
else if (op == OpCode.SYSCALL)
{
var operand = instruction.Operand.ToArray();
result.Add($"{op} {dic[BitConverter.ToUInt32(operand)]}");
}
else
{
if (!instruction.Operand.IsEmpty && instruction.Operand.Length > 0)
{
result.Add($"{op} {dic[BitConverter.ToUInt32(operand)]}");
var operand = instruction.Operand.ToArray();
var asicii = Encoding.Default.GetString(operand);
asicii = asicii.Any(p => p < '0' || p > 'z') ? operand.ToHexString() : asicii;

result.Add($"{op} {(operand.Length == 20 ? new UInt160(operand).ToString() : asicii)}");
}
else
{
result.Add($"{op} {operand.ToHexString()}");
result.Add($"{op}");
}
scripts.RemoveRange(0, operandSize);
onlyOpCode = false;
}
if (operandSizePrefix > 0)
{
var bytes = scripts.Take(operandSizePrefix).ToArray();
var number = bytes.Length == 1 ? bytes[0] : (int)new BigInteger(bytes);
scripts.RemoveRange(0, operandSizePrefix);
var operand = scripts.Take(number).ToArray();

var asicii = Encoding.Default.GetString(operand);
asicii = asicii.Any(p => p < '0' || p > 'z') ? operand.ToHexString() : asicii;

result.Add($"{op} {(number == 20 ? new UInt160(operand).ToString() : asicii)}");
scripts.RemoveRange(0, number);
onlyOpCode = false;
}
if (onlyOpCode)
{
result.Add($"{op}");
}
}
return Environment.NewLine + string.Join("\r\n", result.ToArray());
Expand All @@ -523,7 +486,7 @@ private string ScriptsToOpCode(List<byte> scripts)
/// Returns false if the string is null, or if it is empty, or if each character cannot be printed;
/// otherwise, returns true.
/// </returns>
private bool IsPrintable(string value)
private static bool IsPrintable(string value)
{
return !string.IsNullOrWhiteSpace(value) && value.Any(c => !char.IsControl(c));
}
Expand Down