Add Molecule related features
Background
In the CKB ecosystem, molecule is widely used. We initially have moleculec-es to generate molecule codecs for JS, but it's written in Golang, so it can not run in a JS runtime.
Later, we have related features in the Lumos, see @ckb-lumos/codec and @ckb-lumos/molecule. These two offer compile-time, runtime molecule parsing, and molecule schema defining in JS.
Nowadays, CCC plans to be a successor of Lumos to provide a better developer experience. So, we also want to add the molecule-related feature in CCC.
Plan
- [x] Add molecule codecs to
@ckb-ccc/core. Similar to@ckb-lumos/codecbut with CCC types. #88 - [ ] Add a package
@ckb-ccc/moleculebased on codecs. Similar to@ckb-lumos/molecule. - [x] Decorators to bind codecs to plain TS classes. e.g. #81 #106
@Molecule(codec)
class Script {
...
}
const bytes = Script.from({...}).toBytes();
Script.fromBytes(bytes);
This helps developers to use Molecule.
@homura will start this issue next week
I need to postpone addressing this issue because of higher-priority tasks. I'll likely start it next week
Let me break down the codec feature request.
In CCC, the code is organized using the OO pattern with many classes such as Script, Transaction, etc. The request is to enhance any class by adding a static fromBytes method for the class and a toBytes method for its instance.
The enhancer should take any class and create a new version of that class with the following:
- A new constructor that can create an enhanced instance
type Constructor<
Instance,
Arguments extends unknown[] = any[]
> = new (...args: Arguments) => Instance;
- A new prototype method
toBytes
type ToBytes<Instance> = Instance & { toBytes(): Bytes }
- A new static method
fromBytesto create the enhanced instance
type FromBytes<Class, Instance> = Class & { fromBytes(bytes: Bytes): Instance }
Therefore, a Codec enhancer can be defined as:
type Codec<Class> =
// take any class
Class extends Constructor<infer OriginInstance>
? // add a static `fromBytes` method and a new constructor to create the new instance
FromBytes<Class, ToBytes<OriginInstance>> & Constructor<ToBytes<OriginInstance>>
: // ignore for non-class
never;
To handle the FromBytes part, the codec must know how to convert Bytes in parameters to convert bytes into the constructor parameters.
To handle the ToBytes part, the codec must be able to access the members of the instance to convert them into the Bytes.
declare function enhance<T extends Constructor<any>>(
class_: T,
fromBytes: (bytes: Bytes) => ConstructorParameters<T>,
toBytes: (instance: InstanceType<T>) => Bytes,
): Codec<T>;
TBD: the fromBytes and toBytes callbacks binding design in enhance
https://github.com/microsoft/TypeScript/issues/4881
Currently, using the decorator does not allow for creating a well-typed class. Perhaps CCC should consider using a higher-order approach to achieve this feature. For example, consider the following demonstration:
class InternalScript {
// ...
}
// Enhance an existing class like this
const Script = enhance(InternalScript)
// Or define a class like this
const Script = enhance(class Script {
// ...
})
@Hanssen0 What do you think about this?
Perhaps CCC should consider using a higher-order approach to achieve this feature.
I see no problem. The mixin approach gives us all we want.
We can propose the draft PR first so the progress would be more clear @homura
I have submitted PR #81 to simplify the creation of a CCC class using a helper function. It works with molecule-es and Lumos as a transition program.
To make it work smoother with CCC, we should consider the following steps:
- Introduce
bigintcodecs in CCC to replace theBIfrom Lumos. - Replace Lumos's
Hashwith CCC'sHex. - Regenerate
blockchain.molwith CCC's basic codecs, includingHexandbigintcodecs.
Once these changes are implemented, creating CCC classes would be similar to the case.
@Hanssen0 Do you think these changes meet the requirements?
I have submitted PR #81 to simplify the creation of a CCC class using a helper function. It works with molecule-es and Lumos as a transition program. Do you think these changes meet the requirements?
Yes. This is a good transition plan.
https://github.com/ckb-devrel/ccc/pull/88