-
Notifications
You must be signed in to change notification settings - Fork 102
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
nullable Storage.Get; refactor TokenContract #1214
base: master
Are you sure you want to change the base?
Conversation
This will not affect existing contract, unless they compile it again.... so, not really a big deal, we can add a warning to the contract when they build it. But the behavior should be properly commented. Such that developers can see how it works when they use it. |
@@ -54,11 +54,6 @@ IEnumerator IEnumerable.GetEnumerator() | |||
[OpCode(OpCode.CONVERT, StackItemType.ByteString)] | |||
public static extern explicit operator ByteString(byte[] buffer); | |||
|
|||
[OpCode(OpCode.DUP)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to avoid this change for the moment, only nullables
…to nullable-get # Conflicts: # tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/TestingArtifacts/Nep17ContractTemplate.artifacts.cs
NUMEQUAL can be used in TokenContract |
…into nullable-get
@@ -112,7 +112,9 @@ public extern ByteString this[byte[] key] | |||
[OpCode(OpCode.CAT)] | |||
[OpCode(OpCode.SWAP)] | |||
[Syscall("System.Storage.Get")] | |||
public extern ByteString Get(ByteString key); | |||
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enable nullable at the beginning of the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Maybe I shall just delete the pragma comments
@@ -17,35 +17,49 @@ namespace Neo.SmartContract.Framework | |||
{ | |||
public abstract class TokenContract : SmartContract | |||
{ | |||
protected const byte Prefix_TotalSupply = 0x00; | |||
protected const byte Prefix_Balance = 0x01; | |||
protected static readonly ByteString Prefix_TotalSupply = "\x00"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ByteString is really cheaper when used for storage.get/put. Also static readonly ByteString can be optimized to const now.
@@ -27,11 +27,13 @@ public extern bool IsValid | |||
{ | |||
[OpCode(OpCode.DUP)] | |||
[OpCode(OpCode.ISTYPE, "0x28")] //ByteString | |||
[OpCode(OpCode.SWAP)] | |||
[OpCode(OpCode.JMPIF, "06")] // to SIZE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cheaper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and better for NZ/ISNULL and folding NOT in optimization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this avoids executing SIZE on a possibly null input, and further saves if (input is null)
before using isValid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be in a different PR
@@ -60,14 +60,14 @@ public static void SetOwner(UInt160 newOwner) | |||
|
|||
public static new void Burn(UInt160 account, BigInteger amount) | |||
{ | |||
if (IsOwner() == false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually == false
is a better format as it is reader friendly, but anyway. i dont mind.
# Conflicts: # tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_Linq.cs # tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP11.cs # tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NEP17.cs # tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard11Enum.cs # tests/Neo.SmartContract.Framework.UnitTests/TestingArtifacts/Contract_SupportedStandard17Enum.cs # tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/TestingArtifacts/Nep17ContractTemplate.artifacts.cs # tests/Neo.SmartContract.Template.UnitTests/templates/neocontractowner/TestingArtifacts/OwnableTemplate.artifacts.cs
This PR is a bit risky and may affect existing contract codes. I do not mind abandoning it if not good.
Storage.Get
may actually return null. Ignoring it without generating any warning for the contract developer is not good.Also it is not the best to blindly translate null to BigInteger 0. And it costs GAS to check whether a ByteString is null, when converting it to BigInteger.
Judging null increases contract size, but can be optimized by #1213 .