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

Design Contract model #3

Closed
3 of 10 tasks
Keith-CY opened this issue Oct 8, 2022 · 7 comments
Closed
3 of 10 tasks

Design Contract model #3

Keith-CY opened this issue Oct 8, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@Keith-CY
Copy link
Member

Keith-CY commented Oct 8, 2022

  • extends from Store model
  • default storage layout
  • interfaces
    • deploy(): deploy the contract onto the chain
    • extend(): extends from an existing Contract model for overriding
    • upgrade(): upgrade the contract on the chain
    • run(method: string, params: Array): call a method of the contract to update or get its state(structured data)
    • link(interfaces: Array): instantiate a contract SDK from interfaces
  • metadata extends from that of Store
    • API
@Keith-CY Keith-CY added the documentation Improvements or additions to documentation label Oct 8, 2022
@Keith-CY Keith-CY moved this to 📋 Backlog in CKB JS Backlog Oct 8, 2022
@Keith-CY Keith-CY added documentation Improvements or additions to documentation enhancement New feature or request and removed documentation Improvements or additions to documentation labels Oct 8, 2022
@Keith-CY Keith-CY mentioned this issue Oct 8, 2022
16 tasks
@felicityin
Copy link
Contributor

felicityin commented Oct 9, 2022

Does a virtual machine need to be provided to execute a method of the contract?

@Keith-CY
Copy link
Member Author

Keith-CY commented Oct 9, 2022

Does a virtual machine need to be provided to execute a method of the contract?

A method of a contract model is a state transition function(https://github.com/ckb-js/topics/compare/add-draft-of-kuai-proposal?expand=1#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R31) derives from the logic of the on-chain contract.

Calling the method just outputs a new state but not verifies the transition so a virtual machine is not required.

@felicityin
Copy link
Contributor

Calling the method just outputs a new state but not verifies the transition so a virtual machine is not required.

old state -> compute -> new state

Who will compute? Does the new state can be recomputed by anyone? If not, how to ensure that the new state is correct?

@Keith-CY
Copy link
Member Author

Keith-CY commented Oct 9, 2022

Calling the method just outputs a new state but not verifies the transition so a virtual machine is not required.

old state -> compute -> new state

Who will compute? Does the new state can be recomputed by anyone? If not, how to ensure that the new state is correct?

That's the work of dapp developers.

The framework defines the interface of each component and manages how components work together.

Framework users(dapp developers) follow the convention and implement their own business logic in the components.

How the new state is calculated is determined by framework users, they may adopt various algorithms to generate a new state. And the correctness should be guaranteed by themselves.

@Keith-CY
Copy link
Member Author

How is it going

@yanguoyu
Copy link
Contributor

I only defined three interfaces for Contract, I didn't think of anything else which should be in Contract.

import { OutPointString, State, Store } from "./store";

export default class Contract<T extends State> extends Store<T> {
  create(contract: T) {
    // create a contract cell
  }

  update(key: OutPointString, newContract: T) {
    // update a contract cell
  }

  destory(key: OutPointString) {
    // destory a contract cell
  }
}

@Keith-CY Keith-CY moved this from 📋 Backlog to 🏗 In progress in CKB JS Backlog Nov 17, 2022
@yanguoyu
Copy link
Contributor

Contract maybe like this:

import { ActorURI, MessagePayload } from "../actor";
import Store from "../store";

enum MethodResponseStatus {
  Failed = 0,
  Success
}

interface ContractMethodResponse {
  status: MethodResponseStatus
  reason?: any
  data?: any
}

type MethodType = 'call' | 'cast'

interface ContractMethodInterface {
  [key: ActorURI]: {
    payload: MessagePayload
    result?: ContractMethodResponse
  }
}

export interface State {}

export default class Contract extends Store {

// This is used to update the state when the contract is updated.
  update(oldState: State): State {
    return {}
  }

  run(to: ActorURI, type: 'call' | 'cast', payload: MessagePayload, timeout?: number): Promise<ContractMethodResponse> | void {
    let promise
    switch (type) {
      case 'call':
        promise = this.call(to, payload, timeout)
        break
      case 'cast':
        promise = this.cast(to, payload, timeout)
      default:
        break;
    }
    if (promise) {
      promise.then(res => ({
        status: MethodResponseStatus.Success,
        data: res
      }))
      .catch(err => ({
        status: MethodResponseStatus.Failed,
        reason: err.message ?? err.toString()
      }))
    }
  }

  // link others contracts methods, it may be a service
  link<T extends ContractMethodInterface>(contractAPIs: {
    [P in keyof T]: MethodType
  }) {
    const attacthMethods: Record<ActorURI, PropertyDescriptor> = {}
    Object.keys(contractAPIs).forEach((to: keyof T) => {
      attacthMethods[to as string] = {
        value: (p: any) => this.run(to as string, contractAPIs[to], p),
        enumerable: true
      }
    })
    Object.defineProperties(this, attacthMethods)
    return this as unknown as InstanceType<typeof Contract> & {
      [P in keyof T]: (param: T[P]['payload']) => Promise<T[P]['result']>
    }
  }
}

And the example is like this If I get the .bit contract interface. I can link .bit contract methods

const contract = new Contract()
type BitMethodInterface = {
  'transfter': {
    payload: {
      symbol: symbol
      value: {
        domain: string
      }
    }
    result: ContractMethodResponse
  }
}

const a = contract.link<BitMethodInterface>({
  transfter: 'call'
})
a.transfter({
  symbol: Symbol('c'),
  value: {
    domain: 'aaaa'
  }
})

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
Archived in project
Development

No branches or pull requests

3 participants