-
Notifications
You must be signed in to change notification settings - Fork 71
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
default will be used if call a contract without explicit init #169
Conversation
|
…level contract so init cannot skip
for (const item in c) { | ||
if (c[item].constructor?.deserialize !== undefined) { | ||
this[item] = c[item].constructor.deserialize(this[item]); | ||
} | ||
} | ||
} | ||
else { | ||
throw new Error("Contract state is empty"); | ||
Object.assign(this, c); |
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.
maybe we could make this optional. If default
is defined, then grab it and use it, if not throw error. Since not every contract might want to have a default.
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 believe there is such an option in RS SDK. This design does not allow developers to have an uninitialized contract.
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 see, you guys are right. In RS SDK, developer can right panic in impl Default
to have a "must explicit initialize contract", but here it's not possible. If we throw error in default()
, then because deserialization also calls default()
, it will not work
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.
Looks like Serhii's @Nearbindgen defaultState
proposal is a great solution to the problem, developer can configure the contract to allow or prohibit default there. We're shipping freeze for next week, so let's take more time to get consensus on the solution!
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 am using "request changes" just to the questions get visibility.
I believe we need to provide an end-to-end solution. Extend this PR with modified @NearBindgen that can generate @NearBindgen({defaultState: { param1: 'defaultVal' } })
class Bla extends NearContract() {} |
wouldn't it get impossible to read with more than a couple params? I think implementing a default method is something clean and simple to understand for everyone |
I prefer Serhii's proposal. You can always auto format an object. Or perhaps even import this object from another module or define it above in the module and refer to it. |
we noticed with Ben and Serhii that Making the constructor private is common practice. Does this mean that we cannot derive the state types from the constructor? Or maybe we just need need to duplicate it somewhere else? |
One workaround i can think of is to initialize by assert predecessor == current_account and set some marker state (i.e. initialized = true) in
Not sure if i get your idea perfectly. Do you mean something like: class Bla extends NearContract() {
constructor() {
// can have programmatically private behavior
}
default() {
// instead of call constructor, manually construct a Bla (duplicate part of constructor)
}
} Or: @NearBindgen({defaultState: { param1: 'defaultVal' } })
class Bla extends NearContract() {
constructor() {
// can have programmatically private behavior
}
// default semantic is same as above one, but it's generated from @NearBindgen({defaultState...
} I think either of them will solve this problem |
I think the direction we are going right now is to force users to always give us an instance of the Contract. Right? This is because we cannot serialise the I see that @volovyks is implementing an
|
closed as a superset and better solution is achieved in #200 |
At first time calling a contract, if
init
was not called, thedefault()
will be used to initialize the contract