-
Notifications
You must be signed in to change notification settings - Fork 37
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
Inconsistent UInt160 hashes #276
Comments
@devhawk do we have a unified view of how Hashes should be represented in a readable way? I mean, big- versus little-endian-kind-of-thing. |
@lock9 in my point there's no right or wrong way. This is just representation, and the ecosystem should just agree (standardize) on a way how to display or input these. Or am I wrong? |
IMHO, this directly relates to neo-project/neo#938. FYI, @roman-khimov |
It must be consistent across the applications. The problem here is that it even suggests you to copy the script hash - but the value is not usable as is, you need to revert it. Who could possibly imagine such a thing? It's not even 'explainable' |
Yes, agree.
Yes, that's a usability problem.
Depends on where you want to paste, and which representation the application you want to paste accepts it. Big-endian? Little-endian?
Seniors could imagine such a thing (here), but definitely not newbies or people learning it. 😓
It's explainable, but not usable. Two different things. |
IMHO, this is not only a problem of It's a problem within our entire community on how to standardize hash inputs/types and things like that. It's just more visible in If I get a hash output somewhere in neow3j and paste it to another tool, I'm almost certain that I'd need to reverse it in some scenarios. 😓 |
I want to paste it in my Neo express scripts. That is why it's not consistent. It says that the hash of the contract is "A", but if I try to use "callContract(A)", it won't work. |
The UInt160 type in the C# Neo implementation explicitly reverses the hex string when converting to a string representation public override string ToString()
{
return "0x" + this.ToArray().ToHexString(reverse: true);
} TryParse reverses this, by parsing character pairs from front to back but filling the array buffer from back to front for (int i = 0; i < Length; i++)
if (!byte.TryParse(s.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier, null, out data[Length - i - 1])) Since Neo Express builds on top of the C# Neo implementation, it uses these ToString and TryParse methods. There may be places across the toolkit where we don't reverse the order when converting between binary and string representations, but I would consider those bugs that need to be fixed in the toolkit. I'm sympathetic to the view Roman expressed on this topic - we don't typically treat hash outputs as integers so it feels kind of strange to apply big or little endian encoding. However, at this point we can't change the core platform without breaking a lot of code. The toolkit builds directly on the C# implementation, so it will also continue to use the reversed byte string representation for 160 and 256 bit hashes. Note, Express uses |
I agree that a breaking change is something we should avoid, but I also agree that we need to be as clear and concise as possible, specially integrating our tools. I suggest to introduce a new symbol as prefix for little-endian. NeoExpress could keep using little-endian as default when no prefix symbol is provided but show a warning message to ask the user to use the correct symbol and warn that it will use little-endian as default. |
This sounds like a reasonable idea, though I'd like to get more feedback from the folks on this thread. In particular, I'm interested in what @lock9 thinks. The suggestion here is to make the tools easier to use, but having a two different prefix characters -
Note, adding a new prefix for "non reversed hex encoded hash" is a minor breaking change. Anyone already using that character in their invoke files or other invocation scripts runs the risk of their project breaking since a string that was previously treated as a simple string would now be treated as a hash. However, using a punctuation character such as Furthermore, if a prefixed string can't be parsed into the expected type, it gets treated as a simple string. For example, |
TL;DR: Some context: In this scenario:
The problem: Notes: We also use the tool in Python, Java, and other programming languages. I'm not sure if all of them have the same SDK features available or have similar names. Urgent solution: For the future: My concerns about prefixes and others: The alternative for us is to use the command line, but this has also been a challenge because of inconsistencies in the command line tool. |
@devhawk @JohndeVadoss any opinions/feedback on the previous comment (above)? It seems it negatively affects AxLabs/grantshares#11, in specific if you read AxLabs/grantshares#11 (comment) and AxLabs/grantshares#11 (comment). |
About this ☝️, I believe the easiest is to change the https://github.com/ngdenterprise/neo3-visual-tracker. Therefore, I created an issue for this: N3developertoolkit/neo3-visual-tracker#162 |
I'm sure this would work fine for instructor led tutorials, but how will a developer using these tools for the first time know which one to use?
So can we simply standardize the toolkit to always display UInt160/256 values as reverse encoded hex? |
I think the second option is better. I don't think we ever use script hashes in current format |
We know the issue. We know it can't be fixed. But let me share some NeoGo experience around it and throw in some small idea that maybe can help in mitigating this. We have a CLI that can do contract invocations and many other things. And this CLI has a simple rule --- wherever a script hash can be accepted, an address can also be passed and vice versa. Of course it accepts hashes of one particular kind (reversed ones) and we still can't copy-paste a hash from NeoVM script dump into CLI script, but we can do this for addresses. For contract invocations the way this CLI parses parameters is:
Yeah, it has a lot of magic in it, but in the end what we have is that
and
are absolutely the same invocations. So we have some problems with hashes, but we have zero problems with addresses, they can't be misinterpreted, even though they provide the same 20-byte value inside. And maybe we can leverage that if we're to use them more often, including using them for contract identification purposes. This means providing address representation of every hash wherever we have hashes and accepting addresses wherever hashes are normally accepted. Using NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc instead of 0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5 to identify NEO, NepwUjd9GhqgNkrfXaxj9mmsFhFzGoFuWM instead of 0xd2a4cff31913016155e38e474a2c06d08be276cf to identify GAS, etc. This can't be done overnight, obviously. And this still requires some understanding of things going on, but maybe we can at least think about it, because neo-project/neo#938 can't be fixed at this stage. |
Will it work inside smart-contracts? Can you paste 'NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc' inside the code? It can be a good solution if smart contracts can use this value inside it. I think we need to revert it because it's inconsistent inside Neo Express. If you copy the value from the explorer and paste it inside a invoke file, it won't work. This must be fixed by replacing the existing hash or showing the reverted one. |
It works like this for us in smart contracts (see package docs as well):
This gets compiled into
Conversion is made just because |
I think that if everyone agrees, we can move to an address in the future. Before we have that, could we revert the hex inside the extension? Or at least have an option to view it reverted? |
I agree with @lock9, we should quickly get a solution in the VSCode extension that provides the reverted hex, which can be used without modification (i.e., reverting). If the user can copy the script hash from the UI and paste it back somewhere in the same tool, it should just work. This might seem like a minor thing in the context of the extension, but I think it's a big pain point if you have to tell the user "copy the hash, then go to this converter page, reverse it and paste it back in the same tool, just because". |
While we were all discussing, I took my fun time and already implemented it: N3developertoolkit/neo3-visual-tracker#163 I hope this would ALLEVIATE the pain of this issue -- because it doesn't solve it for good. But it certainly helps. |
Shouldn't we fix the all tools using the wrong order for input instead? Now the user is still in a guessing game because 99% don't have a clue what order should be provided (depending on the tool I'm part of that 99%) |
@ixje I think we should. There are other places where we are showing the incorrect 'hash'. |
Any updates regarding this ticket... its been a long time and as a newb getting in, the extension was confusing. |
@PazBazak No update. We are working on something else to replace (in future). However there shouldn't be a problem in |
Hi, This is not important anymore. We are using other tools. I'm going to close it. |
Hi.
The script hash shown by Neo Express / VS Code extensions seems incorrect.
This is not the correct hash for the contract. The value should be 0x72a951129962cc3dec0220558c7f1064367d395b instead.
The text was updated successfully, but these errors were encountered: