@@ -22,7 +22,7 @@ More details and specifications can be found on [MultiversX Specs](https://githu
2222
2323Currently, 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
2727Once 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
3434Legacy 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
17343Legacy 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