Skip to content

Commit e60a7f7

Browse files
Merge pull request #1096 from multiversx/cleanup-relayed
Relayed transactions V1 & V2 - cleanup
2 parents 759863e + ab104e8 commit e60a7f7

File tree

1 file changed

+1
-211
lines changed

1 file changed

+1
-211
lines changed

docs/developers/relayed-transactions.md

Lines changed: 1 addition & 211 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ More details and specifications can be found on [MultiversX Specs](https://githu
2222

2323
Currently, there are 3 versions of relayed transactions: v1, v2 and v3. In the end, they all have the same effect.
2424

25-
Relayed v2 was meant to bring optimisations in terms of gas usage. But v3 reduces the costs even further, making it our recommendation.
25+
Relayed v2 was meant to bring optimisations in terms of gas usage. But v3 reduces the costs even further, **making it our recommendation**.
2626

2727
Once all applications will completely transition to relayed v3 model, v1 and v2 will be removed.
2828

@@ -34,136 +34,6 @@ Once all applications will completely transition to relayed v3 model, v1 and v2
3434
Legacy version. Please use [version 3](#relayed-transactions-version-3), instead.
3535
:::
3636

37-
A relayed transaction version 1 relies on having the inner transaction JSON serialized and given as an argument to the `relayedTx` protocol function.
38-
39-
It would look like:
40-
41-
```rust
42-
RelayedV1Transaction {
43-
Sender: <Relayer address>
44-
Receiver: <Address that signed the inner transaction>
45-
Value: 0
46-
GasLimit: <move_balance_cost> + length(Data) * <gas_per_data_byte> + <inner transaction gas limit>
47-
Data: "relayedTx" +
48-
"@" + <JSON serialized inner transaction in hexadecimal encoding>
49-
}
50-
```
51-
52-
The inner transaction can have a format like this:
53-
54-
```rust
55-
RelayedV1InnerTransaction {
56-
Sender: <Receiver of the relayed transaction>
57-
Receiver: <Smart Contract address>
58-
Value: 0
59-
GasLimit: <to be determined for each case>
60-
Data: "functionName" +
61-
"@" + <argument in hexadecimal encoding>
62-
...
63-
}
64-
```
65-
66-
However, unlike regular transactions' JSON serialization, the inner transaction that has to be signed has a different
67-
structure:
68-
69-
```js
70-
type Transaction struct {
71-
Nonce uint64
72-
Value *math_big.Int
73-
ReceiverAddress []byte
74-
SenderAddress []byte
75-
GasPrice uint64
76-
GasLimit uint64
77-
Data []byte
78-
ChainID []byte
79-
Version uint32
80-
Signature []byte
81-
Options uint32
82-
}
83-
```
84-
85-
Notice that there are some differences as compared to the regular _frontend_ [transaction structure](/developers/signing-transactions/#general-structure), such:
86-
87-
- `SenderAddress` and `ReceiverAddress` have to be byte arrays instead of bech32 string addresses
88-
- `Value` has to be a big integer, instead of a string
89-
- `ChainID` has to be a byte array instead of a string
90-
- `Signature` has to be a byte array instead of the hex version of it
91-
92-
[comment]: # (mx-context-auto)
93-
94-
### Preparing relayed v1 transaction using mx-sdk-js-core
95-
96-
`mx-sdk-js-core` has built-in support for relayed transactions version 1, by using a builder which allows one to prepare such
97-
a transaction.
98-
99-
Resources:
100-
101-
- [relayedTransactionV1Builder](https://github.com/multiversx/mx-sdk-js-core/blob/main/src/relayedTransactionV1Builder.ts)
102-
- [tests/example](https://github.com/multiversx/mx-sdk-js-core/blob/main/src/relayedTransactionV1Builder.spec.ts)
103-
104-
[comment]: # (mx-context-auto)
105-
106-
### Example
107-
108-
Here's an example of a relayed v1 transaction. Its intent is:
109-
110-
`erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx` will call the function `add` of the contract
111-
`erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd`, while `erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th`
112-
will pay the computation fee
113-
114-
```json
115-
{
116-
"nonce": 2627,
117-
"value": "0",
118-
"receiver": "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
119-
"sender": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
120-
"gasPrice": 1000000000,
121-
"gasLimit": 61040000,
122-
"data": "cmVsYXllZFR4QDdiMjI2ZTZmNmU2MzY1MjIzYTMxMzkzODJjMjI3MzY1NmU2NDY1NzIyMjNhMjI2NzQ1NmU1NzRmNjU1NzZkNmQ0MTMwNjMzMDZhNmI3MTc2NGQzNTQyNDE3MDdhNjE2NDRiNDY1NzRlNTM0ZjY5NDE3NjQzNTc1MTYzNzc2ZDQ3NTA2NzNkMjIyYzIyNzI2NTYzNjU2OTc2NjU3MjIyM2EyMjQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0NjQxNDIzNDc1NTk1MjcxNjMzNDY1NDQ0OTM0Nzk2NzM4N2E0ODc3NjI0NDMwNWE2ODZiNTg0MjM1NzAzMTc3M2QyMjJjMjI3NjYxNmM3NTY1MjIzYTMwMmMyMjY3NjE3MzUwNzI2OTYzNjUyMjNhMzEzMDMwMzAzMDMwMzAzMDMwMzAyYzIyNjc2MTczNGM2OTZkNjk3NDIyM2EzNjMwMzAzMDMwMzAzMDMwMmMyMjY0NjE3NDYxMjIzYTIyNTk1NzUyNmIyMjJjMjI3MzY5Njc2ZTYxNzQ3NTcyNjUyMjNhMjI0ZTMwNzIzMTcwNmYzNzZiNzY0ZjU0NGI0OTQ3NDcyZjc1NmI2NzcyMzg1YTYyNTc2NDU4NjczMTY2NTEzMDc2NmQ3NTYyMzU3OTM0NGY3MzUzNDE3MTM0N2EyZjU5Mzc2YzQ2NTI3OTU3NzM2NzM0NGUyYjZmNGE2OTQ5NDk1Nzc3N2E2YjZkNmM2YTQ5NDE3MjZkNjkzMTY5NTg0ODU0NzkzNDRiNjc0MTQxM2QzZDIyMmMyMjYzNjg2MTY5NmU0OTQ0MjIzYTIyNTY0MTNkM2QyMjJjMjI3NjY1NzI3MzY5NmY2ZTIyM2EzMTdk",
123-
"chainID": "T",
124-
"signature": "44889e788581c8913a00e03f711f9ed3522119030a48fe6c1b3434656670b4b93867213f7a7b5453eafe0884f7447361e1154d26c6e7b2cfa40510159e0e1008",
125-
"version": 1
126-
}
127-
```
128-
129-
The data field (after decoding from base64 to string) is converted to:
130-
131-
```
132-
relayedTx@7b226e6f6e6365223a3139382c2273656e646572223a2267456e574f65576d6d413063306a6b71764d354241707a61644b46574e534f69417643575163776d4750673d222c227265636569766572223a22414141414141414141414146414234755952716334654449347967387a48776244305a686b5842357031773d222c2276616c7565223a302c226761735072696365223a313030303030303030302c226761734c696d6974223a36303030303030302c2264617461223a225957526b222c227369676e6174757265223a224e307231706f376b764f544b4947472f756b6772385a625764586731665130766d75623579344f73534171347a2f59376c465279577367344e2b6f4a69494957777a6b6d6c6a4941726d69316958485479344b6741413d3d222c22636861696e4944223a2256413d3d222c2276657273696f6e223a317d
133-
```
134-
135-
Furthermore, the inner transaction can be easily decoded (hex string to string), resulting in:
136-
137-
```json
138-
{
139-
"nonce": 198,
140-
"sender": "gEnWOeWmmA0c0jkqvM5BApzadKFWNSOiAvCWQcwmGPg=",
141-
"receiver": "AAAAAAAAAAAFAB4uYRqc4eDI4yg8zHwbD0ZhkXB5p1w=",
142-
"value": 0,
143-
"gasPrice": 1000000000,
144-
"gasLimit": 60000000,
145-
"data": "YWRk",
146-
"signature": "N0r1po7kvOTKIGG/ukgr8ZbWdXg1fQ0vmub5y4OsSAq4z/Y7lFRyWsg4N+oJiIIWwzkmljIArmi1iXHTy4KgAA==",
147-
"chainID": "VA==",
148-
"version": 1
149-
}
150-
```
151-
152-
Decoding the base64 fields, we'll get:
153-
154-
- sender: `erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx`
155-
- receiver: `erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd`
156-
- data: `add`
157-
- chain ID: `T`
158-
- signature: `374af5a68ee4bce4ca2061bfba482bf196d67578357d0d2f9ae6f9cb83ac480ab8cff63b9454725ac83837ea09888216c33926963200ae68b58971d3cb82a000`
159-
160-
Regarding the relayed transaction's gas limit, let's check the math.
161-
162-
```js
163-
gasLimit = <move_balance_cost> + length(Data) * <gas_per_data_byte> + <inner transaction gas limit>
164-
gasLimit = 50_000 + 660 * 1500 + 60_000_000
165-
gasLimit = 61040000 // just like the gas limit set in the relayed transaction
166-
```
16737

16838
[comment]: # (mx-context-auto)
16939

@@ -173,86 +43,6 @@ gasLimit = 61040000 // just like the gas limit set in the relayed transaction
17343
Legacy version. Please use [version 3](#relayed-transactions-version-3), instead.
17444
:::
17545

176-
In contrast with version 1, relayed transactions version 2 have only certain fields of the inner transaction included
177-
in the data field, making the payload smaller, therefore the tx fee smaller. It also eliminates the need of calculating
178-
the matching gas limit values between the relayed and inner transactions.
179-
180-
It would look like:
181-
182-
```rust
183-
RelayedV2Transaction {
184-
Sender: <Relayer address>
185-
Receiver: <Address that signed the inner transaction>
186-
Value: 0
187-
GasLimit: <move_balance_cost> + length(Data) * <gas_per_data_byte> + <gas needed for the inner transaction>
188-
Data: "relayedTxV2" +
189-
"@" + <Smart Contract address to be called in hexadecimal encoding>
190-
"@" + <nonce of the receiver in hexadecimal encoding>
191-
"@" + <data field (function name + args) in hexadecimal encoding>
192-
"@" + <the signature of the inner transaction in hexadecimal encoding>
193-
}
194-
```
195-
196-
:::note
197-
Noticing the arguments needed, there are some limitations for the inner transaction: it cannot have call value, a custom gas price or a guardian.
198-
:::
199-
200-
Therefore, when one wants to build such a transaction, the steps would be:
201-
202-
- create the inner transaction (make sure `gasLimit` is set to 0)
203-
- sign it
204-
- fetch the receiver, nonce, data and signature fields and use them in the relayed transaction
205-
206-
[comment]: # (mx-context-auto)
207-
208-
### Preparing relayed v2 transaction using mx-sdk-js-core
209-
210-
`mx-sdk-js-core` has built-in support for relayed transactions version 2, by using a builder which allows one to prepare such
211-
a transaction.
212-
213-
Resources:
214-
215-
- [relayedTransactionV2Builder](https://github.com/multiversx/mx-sdk-js-core/blob/main/src/relayedTransactionV2Builder.ts)
216-
- [tests/example](https://github.com/multiversx/mx-sdk-js-core/blob/main/src/relayedTransactionV2Builder.spec.ts)
217-
218-
[comment]: # (mx-context-auto)
219-
220-
### Example
221-
222-
Here's an example of a relayed v2 transaction. Its intent is:
223-
224-
`erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx` will call the function `add` of the contract
225-
`erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd`, while `erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th`
226-
will pay the computation fee
227-
228-
```json
229-
{
230-
"nonce": 37,
231-
"value": "0",
232-
"receiver": "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
233-
"sender": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
234-
"gasPrice": 1000000000,
235-
"gasLimit": 60372500,
236-
"data": "cmVsYXllZFR4VjJAMDAwMDAwMDAwMDAwMDAwMDA1MDAxZTJlNjExYTljZTFlMGM4ZTMyODNjY2M3YzFiMGY0NjYxOTE3MDc5YTc1Y0AwZkA2MTY0NjRAOWFiZDEzZjRmNTNmM2YyMzU5Nzc0NGQ2NWZjNWQzNTFiYjY3NzNlMDVhOTU0YjQxOWMwOGQxODU5M2QxYzY5MjYyNzlhNGQxNjE0NGQzZjg2NmE1NDg3ODAzMTQyZmNmZjBlYWI2YWQ1ODgyMDk5NjlhY2I3YWJlZDIxMDIwMGI=",
237-
"chainID": "T",
238-
"signature": "2a448b92c16a564a0b1dc8d02fb3a73408decc0aa47d0780a4faa108234d767dc262057b376a9f3c4d9283018c90cb751b55d27c42f59d63cce3ca6213a5ac0a",
239-
"version": 1
240-
}
241-
```
242-
243-
After decoding the data field (base64 to string) we'll get:
244-
245-
```
246-
relayedTxV2@000000000000000005001e2e611a9ce1e0c8e3283ccc7c1b0f4661917079a75c@0f@616464@9abd13f4f53f3f23597744d65fc5d351bb6773e05a954b419c08d18593d1c6926279a4d16144d3f866a5487803142fcff0eab6ad588209969acb7abed210200b
247-
```
248-
249-
Decoding the arguments ([useful resources here](/developers/sc-calls-format/)) we'll get:
250-
251-
- 1st argument: `000000000000000005001e2e611a9ce1e0c8e3283ccc7c1b0f4661917079a75c` => `erd1qqqqqqqqqqqqqpgqrchxzx5uu8sv3ceg8nx8cxc0gesezure5awqn46gtd` (sc address to be called)
252-
- 2nd argument: `0f` => `15` (nonce of the inner transaction)
253-
- 3rd argument: `616464` => `add` (function to be called - no argument needed in this example)
254-
- 4th argument: `9abd13f4f53f3f23597744d65fc5d351bb6773e05a954b419c08d18593d1c6926279a4d16144d3f866a5487803142fcff0eab6ad588209969acb7abed210200b` (the signature of the inner transaction)
255-
25646
[comment]: # (mx-context-auto)
25747

25848
## Relayed transactions version 3

0 commit comments

Comments
 (0)