v1.0.0-preview.24
Pre-releaseWhat's Changed
💥 Go API Breaking Chance
The API of the Go package cadence
improved. These changes only impact users of the Go API of Cadence. These changes had no impact on the language itself or programs written in Cadence.
-
It is no longer possible to access composite fields (
cadence.Composite
types, likecadence.Struct
,cadence.Resource
, etc) by index. TheFields
field got unexported.Details:
- Accessing fields by index makes code dependent on the order of fields in the Cadence type definition, which may change (order is insignificant)
- The order of fields of composite values returned from the chain (e.g. from a script) is planned to be made deterministic in the future. The Go API change prepares for this upcoming encoding change. For more details see #2952
- Accessing fields by name improves code, as it removes possibilities for extracting field values incorrectly (by wrong index)
- There are two ways to get the value of a composite field:
-
If multiple field values are needed from the composite value,
usecadence.FieldsMappedByName
, which returns amap[string]cadence.Value
.For example:
const fooTypeSomeIntFieldName = "someInt" const fooTypeSomeStringFieldName = "someString" // decodeFooEvent decodes the Cadence event: // // event Foo(someInt: Int, someString: String) // // It returns an error if the event does not have the expected fields. func decodeFooEvent(event cadence.Event) (someInt cadence.Int, someString cadence.String, err error) { fields := cadence.FieldsMappedByName(event) var ok bool someIntField := fields[fooTypeSomeIntFieldName] someInt, ok = someIntField.(cadence.Int) if !ok { return cadence.Int{}, "", fmt.Errorf("wrong field type: expected Int, got %T", someInt) } someStringField := fields[fooTypeSomeStringFieldName] someString, ok = someStringField.(cadence.String) if !ok { return cadence.Int{}, "", fmt.Errorf("wrong field type: expected String, got %T", someString) } return someInt, someString, nil }
-
If only a single field value is needed from the composite,
usecadence.SearchFieldByName
. As the name indicates, the function performs a linear search over all fields of the composite. PreferFieldsMappedByName
over repeated calls toSearchFieldByName
.
For example:const fooTypeSomeIntFieldName = "someInt" // fooEventSomeIntField gets the value of the someInt field of the Cadence event: // // event Foo(someInt: Int) // // It returns an error if the event does not have the expected field. func fooEventSomeIntField(event cadence.Event) (cadence.Int, error) { someIntField := cadence.SearchFieldByName(event, fooTypeSomeIntFieldName) someInt, ok := someIntField.(cadence.Int) if !ok { return cadence.Int{}, fmt.Errorf("wrong field type: expected Int, got %T", someInt) } return someInt, nil }
-
-
cadence.GetFieldByName
got renamed tocadence.SearchFieldByName
to make it clear that the function performs a linear search -
cadence.GetFieldsMappedByName
got renamed tocadence.FieldsMappedByName
, to better follow common Go style / naming guides, e.g. https://google.github.io/styleguide/go/decisions#getters -
The convenience method
ToGoValue
ofcadence.Value
, which converts acadence.Value
into a Go value (if possible), got removed. Likewise, the convenience functioncadence.NewValue
, which constructs a newcadence.Value
from the given Go value (if possible), got removed.Details:
- There are many different use cases and needs for methods that convert between Cadence and Go values. When attempting to convert an arbitrary Cadence value into a Go value, there is no "correct" Go type to return in all cases. Likewise, when attempting to convert an arbitrary Go value to Cadence, there might not be a “correct” result type.
- Developers might expect a certain Go type to be returned. For example,
ToGoValue
ofcadence.Struct
returned a Go slice, but some developers might assume and want a Go map; andToGoValue
ofcadence.Dictionary
returned a Go map, but did not account for the case where dictionary keys in Cadence might be types that are invalid in Go maps. - As the return type of
ToGoValue
isany
, developers using the method need to cast to some expected Go type, and hope the returned value is what they expect. - Improvements in the implementation of
ToGoValue
, like in #2531, would have silently broken programs using the function, as the different return value would have no longer matched the developer’s expected type. - Even though these methods and functions got removed from the
cadence
package, developers can still perform the conversion that theToGoValue
methods performed. A future version of Cadence might re-introduce well-defined and strongly-typed conversion functions, that are also consistent with similar conversion functions in other languages (e.g. JavaScript SDK / FCL). - To see what the removed functions and methods did, have a look at the PR that removed them: https://github.com/onflow/cadence/pull/3291/files.
- If you feel like Cadence should re-gain this functionality, please open a feature request, or even consider contributing them through pull requests
🛠 Improvements
- Add runtime check for transaction value moves by @SupunS in #3298
- Add predicate function and test for atree's PersistentSlabStorage.FixLoadedBrokenReferences by @turbolent in #3300
Other Changes
- Merge
release/v1.0.0-preview.23
tomaster
by @github-actions in #3289 - Update update tool config by @turbolent in #3292
- Bump atree version in master branch by @fxamacker in #3293
Full Changelog: v1.0.0-preview.23...v1.0.0-preview.24