-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b0590b7
commit 6b499fe
Showing
1 changed file
with
141 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
- `EVM` - encoded as a Kind byte `1`, followed by the EVM address (20 bytes) | ||
- `ISC` - encoded as a kind byte `2`, followed by an uint32 LE encoding (4 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/). |