# Convenience Layer for Voucher Management on Cartesi

**URL:** <https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401>\
**Category:** Technical Vision Forum\
**Created:** [March 30, 2024, 11:01am UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401 "2024-03-30T11:01:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [March 30, 2024, 11:01am UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/1 "2024-03-30T11:01:06Z")

</div>

# Convenience Layer for Voucher Management on Cartesi

## Objective:

The objective of this proposal is to develop a convenience layer to simplify the process of managing, indexing, and tracking vouchers within the Cartesi ecosystem. This layer will enhance user experience by providing efficient access to voucher-related information and facilitate the monitoring of voucher execution status.

## Proposed Solution:

1. Voucher Creation Command Enhancement:

2. Indexing and Tracking using Reports:

3. Database Structure:

4. GraphQL Integration:

5. Event Listening for Voucher Execution:

## Addressing Challenges:

One of the main challenges is determining the number of tokens in transit from Cartesi Machine (CM) to L1. To overcome this challenge, we propose the following approach:

Implement a tracking mechanism within the convenience layer to monitor the movement of vouchers between CM and L1.  
Integrate with Cartesi’s infrastructure to retrieve information about vouchers in transit.  
Utilize the actual event architecture to capture voucher execution events and update the transit status accordingly.

## Technical details

Code draft to explain the inner workings of the withdraw process, which triggers voucher and report creation.

```ts
// dapp backend within the CM
async function withdrawERC20(owner: string, token: Address, amount: bigint)
    const voucher = await _wallet.withdrawERC20(token, owner, amount)
    const outputIndex = await _dapp.createVoucher(token, payload)
    const voucherMetadata = {
        label: `erc-20-voucher`,
        outputIndex,
        amount,
        owner,
        token,
        /* other params */
    }
    await _dapp.createReport({ payload: createHexPayload(voucherMetadata) })
}

```

We will develop a Proof of Concept (PoC) in the NoNodo to both test and refine the idea.

```go
graphConfig.Resolvers.Mutation().UpdateVoucherMetadata(context, model.VoucherExecutionEvent{
    InputIndex: eventL1.InputIndex,
    OutputIndex: eventL1.OutputIndex,
    ExecutedAt: eventL1.timestamp,
})

```

## Conclusion:

By implementing this convenience layer, we aim to streamline voucher management within the Cartesi ecosystem, providing users with enhanced accessibility and transparency regarding voucher operations. This solution will improve the overall user experience and facilitate the seamless integration of voucher functionality into Cartesi-based applications.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [March 30, 2024, 11:19am UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/2 "2024-03-30T11:19:52Z")

</div>

@milton-cartesi This proposal relies on the existing sendReport functionality, so we anticipate no blocks or changes to the underlying Cartesi Machine. Also, this way, we have the outputIndex 😉

---

<div class="post-metadata">

**Author:** ![tuler](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/tuler/32/30_2.png) [@tuler](https://governance.cartesi.io/u/tuler)\
**Post date:** [March 30, 2024, 1:11pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/3 "2024-03-30T13:11:30Z")

</div>

Why do you need this extra information coming from the machine in a report?

The voucher can be decoded by the application, by knowing the ABI of the destination smart contract.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [March 30, 2024, 5:34pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/4 "2024-03-30T17:34:44Z")

</div>

We need the output index. We may also add more information, such as userdata, as a JSON field in the future. Additionally, @milton-cartesi raised a concern about method name collision.

---

<div class="post-metadata">

**Author:** ![tuler](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/tuler/32/30_2.png) [@tuler](https://governance.cartesi.io/u/tuler)\
**Post date:** [March 30, 2024, 6:07pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/5 "2024-03-30T18:07:40Z")

</div>

I don’t see a reason for more information coming from inside the application. Everything is in the graphql voucher table, except for the contract ABI.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [March 30, 2024, 6:11pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/6 "2024-03-30T18:11:06Z")

</div>

It could also be a good approach to assign meaning to other types of vouchers. In the Cartesi Store experiment, we may need to mint the NFT within the Cartesi Machine (CM) and then call a specific method to create the NFT on Layer 1, considering that the NFT originates from within the CM.

> <https://github.com/Calindra/cartesi-store/blob/28d85ec0224268bf78d331219abf7580a0083a11/onchain/contracts/NonFunToken.sol#L28>

We can add the NFT attributes to the “userdata” field.

---

<div class="post-metadata">

**Author:** ![guidanoli](https://avatars.discourse-cdn.com/v4/letter/g/3bc359/32.png) [@guidanoli](https://governance.cartesi.io/u/guidanoli)\
**Post date:** [April 1, 2024, 12:41pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/7 "2024-04-01T12:41:14Z")

</div>

I tend to agree with @tuler that reports are not really necessary in order to extract “essential details required for indexing and tracking vouchers”. They can be extracted from vouchers themselves. More specifically, you can decode each voucher payload as a Solidity function data against a set of known ABIs.

From the examples you mentioned, you should be good with the ABIs of token standards (ERC-20, ERC-721, ERC-1155) and the application contract (for ETH withdrawals as of Cartesi Rollups SDK v1).

I believe this approach of inferring the beneficiary address from the voucher itself rather than from an accompanying report is more robust, because you are less prone to inconsistencies (e.g. you create an ERC-20 withdrawal voucher for Alice but emit a report saying it’s for Bob).

There are several ways to decode Solidity function data. I personally like viem’s [`decodeFunctionData`](https://viem.sh/docs/contract/decodeFunctionData).

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 1:41pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/8 "2024-04-01T13:41:23Z")

</div>

One point I agree with @milton-cartesi is that, we know it’s difficult in practice, however it would be theoretically possible for a random method to collide with the 4 bytes of the signature hash of an ABI method (ethers, erc-20, 721, 1155) mapped.

> [@guidanoli](#):
>
> because you are less prone to inconsistencies (e.g. you create an ERC-20 withdrawal voucher for Alice but emit a report saying it’s for Bob).

We will encapsulate the common cases to prevent errors and inconsistencies.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 1:45pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/9 "2024-04-01T13:45:16Z")

</div>

While discussing that topic with @tuler , I came up with a similar idea to externalize part of the state to IPFS, this time involving notices. A special type of notice, with a special header, could be used to send a file to IPFS.

---

<div class="post-metadata">

**Author:** ![tuler](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/tuler/32/30_2.png) [@tuler](https://governance.cartesi.io/u/tuler)\
**Post date:** [April 1, 2024, 1:59pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/10 "2024-04-01T13:59:43Z")

</div>

> [@fabio.oshiro](#):
>
> One point I agree with @milton-cartesi is that, we know it’s difficult in practice, however it would be theoretically possible for a random method to collide with the 4 bytes of the signature hash of an ABI method (ethers, erc-20, 721, 1155) mapped.

This is not possible within the context of a smart contract AFAIK.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 3:20pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/11 "2024-04-01T15:20:29Z")

</div>

Just to clarify our discussion, here is the method we’ve been referring to:

```auto
/**
 * Returns the function selector for a given function definition.
 *
 * @example
 * const selector = toFunctionSelector('function ownerOf(uint256 tokenId)')
 * // 0x6352211e
 */
export const toFunctionSelector = (fn: string | AbiFunction) =>
  slice(toSignatureHash(fn), 0, 4)

```

That code is from the viem package.

---

<div class="post-metadata">

**Author:** ![tuler](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/tuler/32/30_2.png) [@tuler](https://governance.cartesi.io/u/tuler)\
**Post date:** [April 1, 2024, 3:47pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/12 "2024-04-01T15:47:33Z")

</div>

You can’t have a collision in a contract.

> <https://ethereum.stackexchange.com/questions/46182/how-does-the-evm-resolve-method-id-collision/46188#46188>

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 4:39pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/13 "2024-04-01T16:39:40Z")

</div>

Not in the same contract

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 4:56pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/14 "2024-04-01T16:56:32Z")

</div>

The point is, we can use the existing mechanics to externalize and give more meaning to the vouchers. I believe it’s worth exploring this path, it could be connected to a way to send files to IPFS, like NFT metadata.

---

<div class="post-metadata">

**Author:** ![milton-cartesi](https://avatars.discourse-cdn.com/v4/letter/m/9f8e36/32.png) [@milton-cartesi](https://governance.cartesi.io/u/milton-cartesi)\
**Post date:** [April 1, 2024, 6:27pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/15 "2024-04-01T18:27:28Z")

</div>

I’m a bit confused here, but I think I understand some things. Here are my opinions and doubts:

1. I believe the proposal is for a component/service to run alongside the node, which would monitor vouchers being emitted and provide an enhanced GraphQL endpoint for querying them in a more convenient way. Is that it @fabio.oshiro? And, on top of that, you are maybe also proposing some wrapper framework that would run inside the machine?

2. @tuler the collision issue that is being considered is not for collision within a contract. Their original idea AFAIK is that the layer would only check the payload against a function signature, but without knowing whether the destination address implements a specific ABI or not. In other words, if the function signature matches that of `transfer(address,uint256)` then it would assume it is an ERC20 transfer, regardless of the destination. In that scenario, IMHO a collision is possible against some random method from some other random contract.

3. @fabio.oshiro I’m really confused about your “userdata” idea. The way you put it, it seemed to be similar to the voucher’s parameters: if you want to call a method to create an NFT on Layer 1, just emit the voucher, right…? Or were you proposing something similar to the “labels” metadata idea?

---

<div class="post-metadata">

**Author:** ![tuler](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/tuler/32/30_2.png) [@tuler](https://governance.cartesi.io/u/tuler)\
**Post date:** [April 1, 2024, 6:43pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/16 "2024-04-01T18:43:16Z")

</div>

> [@milton-cartesi](#):
>
> Their original idea

Whos/what idea?

> [@milton-cartesi](#):
>
> the layer would only check the payload against a function signature, but without knowing whether the destination address implements a specific ABI or not.

That’s a bad idea.  
Use the contract address, and the ABI, and the payload, to properly present the voucher in the UI.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 7:26pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/17 "2024-04-01T19:26:16Z")

</div>

> [@milton-cartesi](#):
>
> - I believe the proposal is for a component/service to run alongside the node, which would monitor vouchers being emitted and provide an enhanced GraphQL endpoint for querying them in a more convenient way. Is that it @fabio.oshiro? And, on top of that, you are maybe also proposing some wrapper framework that would run inside the machine?

Yes, @milton-cartesi that’s correct. The proposal involves implementing a service to run in the node. This component would monitor the emission of vouchers and enhance the GraphQL endpoint for querying them in a more user-friendly manner. Additionally, it aims to address issues such as hash selector collisions and provide a wrapper framework to facilitate the development.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 1, 2024, 7:34pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/18 "2024-04-01T19:34:31Z")

</div>

> [@milton-cartesi](#):
>
> @fabio.oshiro I’m really confused about your “userdata” idea. The way you put it, it seemed to be similar to the voucher’s parameters: if you want to call a method to create an NFT on Layer 1, just emit the voucher, right…? Or were you proposing something similar to the “labels” metadata idea?

It could be similar to labels or even include additional information beyond what’s in the payload to L1, such as NFT attributes: attack, defense, hp, etc. When a token/NFT originates within the CM and is later converted into a voucher, it could be beneficial to include certain attributes for presentation purposes.

```auto
// L1 lacks the metadata
function mintNFT(address collector, uint256 tokenId, string memory _tokenURI) public {
    require(authority == msg.sender || owner() == msg.sender, "Only the authority can mint NFTs");
    _safeMint(collector, tokenId); 
    _tokenURIs[tokenId] = _tokenURI;
}

```

---

<div class="post-metadata">

**Author:** ![milton-cartesi](https://avatars.discourse-cdn.com/v4/letter/m/9f8e36/32.png) [@milton-cartesi](https://governance.cartesi.io/u/milton-cartesi)\
**Post date:** [April 2, 2024, 1:05am UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/19 "2024-04-02T01:05:20Z")

</div>

> [@tuler](#):
>
> Whos/what idea?

@fabio.oshiro’s / Calindra’s

> [@tuler](#):
>
> That’s a bad idea.  
> Use the contract address, and the ABI, and the payload, to properly present the voucher in the UI.

I agree. I do not support the idea either (of automagically detecting voucher types), I was only explaining what they had in mind.

---

<div class="post-metadata">

**Author:** ![fabio.oshiro](https://dub1.discourse-cdn.com/flex005/user_avatar/governance.cartesi.io/fabio.oshiro/32/34_2.png) [@fabio.oshiro](https://governance.cartesi.io/u/fabio.oshiro)\
**Post date:** [April 2, 2024, 8:21pm UTC](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401/20 "2024-04-02T20:21:58Z")

</div>

I talked to @milton-cartesi , @tuler and @guidanoli, and we’re going to use [WhatsABI](https://github.com/shazow/whatsabi) to try to download the ABI of the contract to have the correct method signature. If we can’t find it, we can infer what the method is and mark it as an inference.

[Next page](https://governance.cartesi.io/t/convenience-layer-for-voucher-management-on-cartesi/401.md?page=2)
