Batch Transactions
Introduction
In some cases, aepp developer may need to send a set of transactions at once. The SDK provides optimizations for this scenario but it also requires additional effort by the developer. This guide covers specific cases with suggestions on how to proceed with them to produce a sequence of requests in an efficient way.
Multiple spend transactions
Obviously, multiple spends may be done like:
for (const { address, amount } of spends) {
await aeSdk.spend(amount, address)
}
- request the sender data (its type and nonce)
- verify the transaction (including additional requests)
- wait until the transaction is mined
It can be avoided by making spends as:
const base = (await aeSdk.api.getAccountNextNonce(await aeSdk.address())).nextNonce
await Promise.all(spends.map(({ amount, address }, idx) =>
aeSdk.spend(amount, address, { nonce: base + idx, verify: false, waitMined: false }))
)
spends
array.
Multiple contract static calls
Basically, the dry-run endpoint of the node is used to run them. Doing requests one by one, like
const results = []
for (const d of data) {
results.push(await contractInstance.methods.foo(d))
}
const base = (await aeSdk.api.getAccountNextNonce(await aeSdk.address())).nextNonce
const results = await Promise.all(
data.map((d, idx) => contractInstance.methods.foo(d, { nonce: base + idx, combine: true }))
)
combine
flag SDK would put all of them into a single dry-run request. Also, it is necessary to generate increasing nonces on the aepp side to avoid nonce-already-used errors.
This approach has another limitation: by default, dry-run is limited by 6000000 gas. This is enough to execute only 32 plain contract calls. it can be avoided by:
- increasing the default gas limit of restricted dry-run endpoint in node configuration
- decreasing the gas limit of each static call
- using a debug dry-run endpoint instead of the restricted one