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

KIP-0032: Cross-Chain Function Call Syntax Enhancement #65

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions kip-0032.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
KIP: "0032"
Title: Cross-Chain Function Call Syntax Enhancement by Including Chain ID in Function Calls
Author: @DaisukeFlowers
Status: Draft
Type: Improvement
Category: Pact
Created: 2024-11-04
---

# KIP-0032: Cross-Chain Function Call Syntax Enhancement by Including Chain ID in Function Calls

## Abstract

Introducing a syntax that includes the chain ID in the function call to enable direct cross-chain interactions. This proposal aims to simplify cross-chain workflows by allowing function calls across chains, which is currently limited to data transfer only. With this change, cross-chain communication becomes more intuitive and flexible, making the development of complex interactions more efficient.

## Motivation

Kadena's current cross-chain communication utilizes `defpact`, `yield`, and `resume` constructs to transfer data between chains. While effective for data exchange, this approach is limited and can become complex for developers who need to execute functions or retrieve information from other chains directly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @DaisukeFlowers, I'm rewording this a bit to make sure I understand the main ask:

  • Is this asking for smart contracts to call functions in other chains?
  • This would be similar to how smart contracts can currently call functions in other smart contracts within the same chain, correct?

Copy link
Contributor

@LindaOrtega LindaOrtega Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example of reading the state in another chain:
Let say the following Pact code is being executed on Chain 0:

(free.token.get-balance ACCOUNT_A)
(1.free.token.get-balance ACCOUNT_A)

(free.token.get-balance ACCOUNT_A) will retrieve the account balance of ACCOUNT_A in Chain 0.
But (1.free.token.get-balance ACCOUNT_B) will retrieve the account balance of ACCOUNT_A in Chain 1.

Example of changing the state in another chain:
Let say the following Pact code is being executed on Chain 0:

(2.free.token.transfer ACCOUNT_A ACCOUNT_B 2.5)
(free.someOtherToken.transfer ACCOUNT_B ACCOUNT_A 1.0)

(2.free.token.transfer ACCOUNT_A ACCOUNT_B 2.5) will transfer funds from these accounts on chain 2.
(free.someOtherToken.transfer ACCOUNT_B ACCOUNT_A 1.0) will transfer funds from these accounts on chain 0.


aka, being able to execute a Pact function on Chain 2 while executing other code in Chain 0, for example.
Are these interpretations correct?

Copy link
Author

@DaisukeFlowers DaisukeFlowers Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @LindaOrtega, all statements are correct.
The function will be executed as if on the target chain.
In the last example:
If the following is executed on chain 0
(2.free.token.transfer ACCOUNT_A ACCOUNT_B 2.5)
ACCOUNT_A from chain 2 will transfer to ACCOUNT_B from chain 2.
The function will be executed as if in chain 2 from chain 0.

Copy link
Contributor

@LindaOrtega LindaOrtega Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aw, I see!

TL;DR:
Unfortunately, being able to execute code on multiple chains (especially code that changes the state) is not feasible at the moment with the current chainweb-node architecture.

That means that chain X cannot run code on chain Y directly.

Longer Explanation:
Each chain has its own block and Pact history. You can think of the different chains in Kadena as "mini" blockchains in their own right; and together they make up the bigger Kadena network. Its just that the consensus algorithm of the entire network requires hash information from all chains (see the Whitepaper for more details).

So for the different chains to communicate with each other about their respective Pact state, they need to use a "bridge" (of sorts). This "bridge" is what we usually call cross-chain operations.


But I would like to explore the problem you brought up a little bit more, and see if there is another solution that can work. For example, there might be a way to make using defPact easier.

  1. Could you elaborate on the use case you had in mind that needed the feature being proposed?
  2. And is it something that's feasible (but complex) to do right now?
  3. Is there a preference for being able to read the state of different chains? Or is the preference for being able to execute code that changes the state in another chain?

edit: added the third question

Copy link
Author

@DaisukeFlowers DaisukeFlowers Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand.
What I'm trying to accomplish is the possibility to pay dividends.
In order to do that, all shares contracts in all chains need to know how much KDA they have to calculate the dividend per share.
If the shares contract in chain 0 has 50 KDA, shares contract in chain 1 has 50 KDA and shares contract in chain 2 has 0 KDA, and all my shares are in contract in chain 2, even if it has 0 KDA, I would still be entitle of the corresponding of the total 100 KDA that the company holds.
In order to do this, each chain needs to transmit what they hold to all other chains and once all chains know how much they hold they can calculate how much dividend per share is, and do the analysis of how much they have and how much they owe, and then if they owe more than they have, all shares contracts in different chains will need to balance and transfer between them to have enough to pay the dividends they owe.
To do all this, is a big amount of cross-chain transfers and blocks.
It would be easier if I could just read the tables in other chains (call functions from other chains like get-balance), but that will not be possible.
The other option is to do it in one chain, I have that contract 100% functional but I really want to do it multi-chain.
I know is possible, I just need to find a good way to test all this cross-chain interaction ( looking forward cross-chain in RELP, I hope we get it soon)
Thanks you @LindaOrtega

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can absolutely do this multi-chain. But this will require typical techniques from bridges and more generally distributed systems, like locking up shares for some period so that the chains can all agree for that period.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @edmundnoble, I found it better to calculate the time weighted average of each share as part of the transfer function and just use that number to calculate the dividend per share than having a locking system.
Once I can test and make sure everything works as intended in cross-chain I would love to share it with you and get some feedback.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Time-weighting sounds feasible, just as long as you've calculated that the time-weight is sufficient to prevent any way you'd game the system by doing other things with the shares in the meantime.


### Why This Change?
1. **Expanding Cross-Chain Interactions**: Allowing direct function calls across chains enables richer, more flexible cross-chain workflows, enhancing Kadena’s interoperability capabilities.
2. **Streamlining Development**: The proposed syntax reduces the need for complex `yield` and `resume` sequences, making code more readable and easier to maintain.
3. **Enhanced Usability**: Developers gain a simpler and more intuitive way to manage cross-chain communication, which enhances productivity and reduces the risk of errors in complex multi-chain workflows.

## Detailed Specification

### New Syntax: `chain.namespace.contract.function`
- **Parameters**:
- `chain`: The ID of the target chain.
- `namespace`: The namespace of the contract.
- `contract`: The name of the contract.
- `function`: The function to be called.

### Function Call
- **Current form**: `(namespace.contract.function PARAMETERS)`
- **Proposed form**: `(chain.namespace.contract.function PARAMETERS)`

If no chain ID is specified, the function defaults to the chain of the executing contract.

## Example Usage

### Current Cross-Chain Data Transfer (with `defpact`)
```pact
(defpact crossChainTransfer
(step "Step 1" (yield { "data-key": data-value }))
(step "Step 2" (resume { "data-key":= data-value })))
```

### Proposed Cross-Chain Function Call
```pact
(chain123.namespaceX.contractY.functionZ PARAMETERS)
```

This allows developers to call `functionZ` directly on `chain123` within `namespaceX.contractY`.

### Example
```pact
;; Current usage
(free.token.get-balance ACCOUNT)

;; Proposed usage
(1.free.token.get-balance ACCOUNT)
```

## Backward Compatibility

The proposal is fully backward-compatible. The existing `(namespace.contract.function PARAMETERS)` syntax remains unchanged for single-chain calls.

## Benefits

- **Enhanced Interoperability**: Directly execute functions on other chains, expanding cross-chain capabilities.
- **Developer Productivity**: Simplifies code and reduces the learning curve for managing cross-chain operations.
- **Flexible Workflows**: Allows seamless multi-chain interactions without multi-step, complex setups.