Skip to content

Commit

Permalink
TIP 51
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgemmsilva committed Nov 10, 2023
1 parent b0590b7 commit 5431a8b
Showing 1 changed file with 141 additions and 0 deletions.
141 changes: 141 additions & 0 deletions tips/TIP-0051/tip-0051.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
tip: 51
title: ISC request Output metadata encoding
description: describes the encoding to send request outputs to an ISC chain
author: Jorge Silva (@jorgemmsilva) <[email protected]>
status: Draft
type: Standards
layer: L2 Smart Contracts
created: 2023-09-27
requires: None
replaces: None
---

## Summary

This document describes the encoding of an ISC request to be included in a request output Metadata feature.

## Motivation

In order to interact with ISC chains using L1 output requests, the metadata for a request must be specified in the Metadata feature of the created output.

## Specification

(LE stands for Little Endian, BE stands for Big Endian.)

### Request Metadata

Encoding of the request metadata follows the following structure, in strict order:

| Description | Type | Encoding |
| ---------------- | ---------------- | ---------------------------------------------------------------------------------- |
| SenderContract | ContractIdentity | [custom](./###ContractIdentity) |
| TargetContract | HName (uint32) | LE encoding uint32 (4 bytes) |
| TargetEntryPoint | HName (uint32) | LE encoding uint32 (4 bytes) |
| GasBudget | uint64 | LE encoding uint64 (8 bytes) - Value +1 <br/>(1 must be encoded as 2, 3 as 4 ,etc) |
| Params | Dictionary | [custom](./###Dictionary) |
| Allowance | Assets | [custom](./###Assets) |


### Hname

The hnames can be calculated from: Blake2B Hash of an UTF-encoded string, then taking the initial 4 bytes as a LE encoded uint32:

```go
Blake2B("accounts") // yields 0x3c4b5e02.....
```

### ContractIdentity

Is used to identify a contract on a given chain (for the time being, contracts can only be of type `EVM` or `ISC`).

When sending requests from non-chain identities (regular user wallet), the `ContractIdentity` should always be `null`.

There are 3 types of `ContractIdentity`:

- `null` - encoded as a single Kind `0` byte
- `ISC` - encoded as a kind byte `1`, followed by an uint32 LE encoding (4 bytes)
- `EVM` - encoded as a Kind byte `2`, followed by the EVM address (20 bytes)

### Dictionary

A dictionary is a set of Key/Value pairs.
Must be encoded in the following way:

- Length Prefix (number of kv pairs) using [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137)
- Each kv pair: [
- `Key` bytes, prefixed with size in [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137)
- \+ `Value` bytes prefixed with size in [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137)]

### Assets

The Assets encoding starts with a bitmask:

```go
hasBaseTokens = 0x80
hasNativeTokens = 0x40
hasNFTs = 0x20
```

followed by the 3 optional parts, in strict order:

- Base Tokens - uint64 - LE encoding
- Native Tokens:
- length prefix (number of different tokens - uint16 LE encoding)
- \+ each [TokenID (38 bytes) + amount ([uint256 special encoding](./###Uint256))]
- NFTs
- length prefix (number of NFTs - uint16 LE encoding)
- \+ the bytes off all the NFTIDs (32 bytes each)

### Uint256

Uint256 values are encoded using BE and unused bytes removed. Must prefixed by the length of the encoded bytes using the [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137).

## Example

Follows an example of a deposit from L1 to an EVM address on a target chain:

```go
{
SenderContract: nil,
TargetContract: 1011572226 ( = 0x3c4b5e02),
EntryPoint: 603251617 ( = 0x23f4e3a1),
GasBudget: 10000,
Params: [
{ k: "a", v: EthereumAgentID(
address: 0xE913CAc59E0bA840039aDD645D5df83C294CC230,
chainID: 0xe14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f4)
},
],
Allowance: {
BaseTokens:0,
NativeTokens:[
{
ID: 0x08e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f40100000000,
Amount: 50
}
],
NFTs: [],
},
}
```

The `TargetContract` is `"accounts"` and `TargetEntrypoint` is `"transferAllowanceTo"`.

The `EthereumAgentID` is encoded as: kind byte of value 3 + chainID bytes + ethereumAddress bytes.

results in the following metadata:

```hex
0x00025e4b3ca1e3f423914e0101613503e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f4e913cac59e0ba840039add645d5df83c294cc230400108e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f401000000000132
```

## Libraries

The Wasp repo already provides function to Encode/Decode request metadata (in Go).

A javascript library should be produced to be re-used across client applications.

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 comments on commit 5431a8b

Please sign in to comment.