|
| 1 | +--- |
| 2 | +tip: 51 |
| 3 | +title: ISC request Output metadata encoding |
| 4 | +description: describes the encoding to send request outputs to an ISC chain |
| 5 | +author: Jorge Silva (@jorgemmsilva) <[email protected]> |
| 6 | +status: Draft |
| 7 | +type: Standards |
| 8 | +layer: L2 Smart Contracts |
| 9 | +created: 2023-09-27 |
| 10 | +requires: None |
| 11 | +replaces: None |
| 12 | +--- |
| 13 | + |
| 14 | +## Summary |
| 15 | + |
| 16 | +This document describes the encoding of an ISC request to be included in a request output Metadata feature. |
| 17 | + |
| 18 | +## Motivation |
| 19 | + |
| 20 | +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. |
| 21 | + |
| 22 | +## Specification |
| 23 | + |
| 24 | +(LE stands for Little Endian, BE stands for Big Endian.) |
| 25 | + |
| 26 | +### Request Metadata |
| 27 | + |
| 28 | +Encoding of the request metadata follows the following structure, in strict order: |
| 29 | + |
| 30 | +| Description | Type | Encoding | |
| 31 | +| ---------------- | ---------------- | ---------------------------------------------------------------------------------- | |
| 32 | +| SenderContract | ContractIdentity | [custom](./###ContractIdentity) | |
| 33 | +| TargetContract | HName (uint32) | LE encoding uint32 (4 bytes) | |
| 34 | +| TargetEntryPoint | HName (uint32) | LE encoding uint32 (4 bytes) | |
| 35 | +| GasBudget | uint64 | LE encoding uint64 (8 bytes) - Value +1 <br/>(1 must be encoded as 2, 3 as 4 ,etc) | |
| 36 | +| Params | Dictionary | [custom](./###Dictionary) | |
| 37 | +| Allowance | Assets | [custom](./###Assets) | |
| 38 | + |
| 39 | + |
| 40 | +### Hname |
| 41 | + |
| 42 | +The hnames can be calculated from: Blake2B Hash of an UTF-encoded string, then taking the initial 4 bytes as a LE encoded uint32: |
| 43 | + |
| 44 | +```go |
| 45 | +Blake2B("accounts") // yields 0x3c4b5e02..... |
| 46 | +``` |
| 47 | + |
| 48 | +### ContractIdentity |
| 49 | + |
| 50 | +Is used to identify a contract on a given chain (for the time being, contracts can only be of type `EVM` or `ISC`). |
| 51 | + |
| 52 | +When sending requests from non-chain identities (regular user wallet), the `ContractIdentity` should always be `null`. |
| 53 | + |
| 54 | +There are 3 types of `ContractIdentity`: |
| 55 | + |
| 56 | +- `null` - encoded as a single Kind `0` byte |
| 57 | +- `EVM` - encoded as a Kind byte `1`, followed by the EVM address (20 bytes) |
| 58 | +- `ISC` - encoded as a kind byte `2`, followed by an uint32 LE encoding (4 bytes) |
| 59 | + |
| 60 | +### Dictionary |
| 61 | + |
| 62 | +A dictionary is a set of Key/Value pairs. |
| 63 | +Must be encoded in the following way: |
| 64 | + |
| 65 | +- Length Prefix (number of kv pairs) using [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137) |
| 66 | +- Each kv pair: [ |
| 67 | + - `Key` bytes, prefixed with size in [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137) |
| 68 | + - \+ `Value` bytes prefixed with size in [Optimized Size Encode](https://github.com/iotaledger/wasp/blob/c362291b053f70c9b14a16961dd74b3b4176bba5/packages/util/rwutil/convert.go#L108-L137)] |
| 69 | + |
| 70 | +### Assets |
| 71 | + |
| 72 | +The Assets encoding starts with a bitmask: |
| 73 | + |
| 74 | +```go |
| 75 | +hasBaseTokens = 0x80 |
| 76 | +hasNativeTokens = 0x40 |
| 77 | +hasNFTs = 0x20 |
| 78 | +``` |
| 79 | + |
| 80 | +followed by the 3 optional parts, in strict order: |
| 81 | + |
| 82 | +- Base Tokens - uint64 - LE encoding |
| 83 | +- Native Tokens: |
| 84 | + - length prefix (number of different tokens - uint16 LE encoding) |
| 85 | + - \+ each [TokenID (38 bytes) + amount ([uint256 special encoding](./###Uint256))] |
| 86 | +- NFTs |
| 87 | + - length prefix (number of NFTs - uint16 LE encoding) |
| 88 | + - \+ the bytes off all the NFTIDs (32 bytes each) |
| 89 | + |
| 90 | +### Uint256 |
| 91 | + |
| 92 | +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). |
| 93 | + |
| 94 | +## Example |
| 95 | + |
| 96 | +Follows an example of a deposit from L1 to an EVM address on a target chain: |
| 97 | + |
| 98 | +```go |
| 99 | +{ |
| 100 | + SenderContract: nil, |
| 101 | + TargetContract: 1011572226 ( = 0x3c4b5e02), |
| 102 | + EntryPoint: 603251617 ( = 0x23f4e3a1), |
| 103 | + GasBudget: 10000, |
| 104 | + Params: [ |
| 105 | + { k: "a", v: EthereumAgentID( |
| 106 | + address: 0xE913CAc59E0bA840039aDD645D5df83C294CC230, |
| 107 | + chainID: 0xe14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f4) |
| 108 | + }, |
| 109 | + ], |
| 110 | + Allowance: { |
| 111 | + BaseTokens:0, |
| 112 | + NativeTokens:[ |
| 113 | + { |
| 114 | + ID: 0x08e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f40100000000, |
| 115 | + Amount: 50 |
| 116 | + } |
| 117 | + ], |
| 118 | + NFTs: [], |
| 119 | + }, |
| 120 | +} |
| 121 | +``` |
| 122 | + |
| 123 | +The `TargetContract` is `"accounts"` and `TargetEntrypoint` is `"transferAllowanceTo"`. |
| 124 | +the `EthereumAgentID` is encoded as: kind byte of value 3 + chainID bytes + ethereumAddress bytes. |
| 125 | + |
| 126 | +results in the following metadata: |
| 127 | + |
| 128 | +```hex |
| 129 | +0x00025e4b3ca1e3f423914e0101613503e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f4e913cac59e0ba840039add645d5df83c294cc230400108e14c3499349cb8d2fd771e09829883e4ecfae02e6b09c9b6a0fb3c7504b4e2f401000000000132 |
| 130 | +``` |
| 131 | + |
| 132 | +## Libraries |
| 133 | + |
| 134 | +The Wasp repo already provides function to Encode/Decode request metadata (in Go). |
| 135 | + |
| 136 | +A javascript library should be produced to be re-used across client applications. |
| 137 | + |
| 138 | +## Copyright |
| 139 | + |
| 140 | +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
0 commit comments