Skip to content
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

Add Molecule related features #33

Open
3 tasks
Hanssen0 opened this issue Aug 28, 2024 · 8 comments
Open
3 tasks

Add Molecule related features #33

Hanssen0 opened this issue Aug 28, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@Hanssen0
Copy link
Member

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

  • Add molecule codecs to @ckb-ccc/core. Similar to @ckb-lumos/codec but with CCC types.
  • Add a package @ckb-ccc/molecule based on codecs. Similar to @ckb-lumos/molecule.
  • Decorators to bind codecs to plain TS classes. e.g.
@Molecule(codec)
class Script {
...
}
const bytes = Script.from({...}).toBytes();
Script.fromBytes(bytes);

This helps developers to use Molecule.

@Keith-CY
Copy link

@homura will start this issue next week

@homura
Copy link

homura commented Sep 19, 2024

I need to postpone addressing this issue because of higher-priority tasks. I'll likely start it next week

@homura
Copy link

homura commented Sep 27, 2024

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:

  1. A new constructor that can create an enhanced instance
type Constructor<
  Instance, 
  Arguments extends unknown[] = any[]
> = new (...args: Arguments) => Instance;
  1. A new prototype method toBytes
type ToBytes<Instance> = Instance & { toBytes(): Bytes }
  1. A new static method fromBytes to 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

@homura
Copy link

homura commented Oct 10, 2024

microsoft/TypeScript#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?

@Hanssen0
Copy link
Member Author

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.

@Hanssen0 Hanssen0 added the enhancement New feature or request label Oct 16, 2024
@Keith-CY
Copy link

We can propose the draft PR first so the progress would be more clear @homura

@homura
Copy link

homura commented Oct 21, 2024

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 bigint codecs in CCC to replace the BI from Lumos.
  • Replace Lumos's Hash with CCC's Hex.
  • Regenerate blockchain.mol with CCC's basic codecs, including Hex and bigint codecs.

Once these changes are implemented, creating CCC classes would be similar to the case.

@Hanssen0 Do you think these changes meet the requirements?

@Hanssen0
Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants