Transaction Dependency
Source of Dependency
A transaction id is generated when a transaction is published to a Blockchain Node. The id allows tracking of the transaction status.
The transaction id can be used as dependency for future transactions.
Set Dependency
Dependency is set with dependsOn
(docs.vechain.org (opens in a new tab)).
A single transaction id is referenced. The dependency is not required to processed yet. It can be pending or yet unknown on the network.
Waiting for it …
The transaction pool is checked on each new block. If a transaction dependency was fulfilled, it moves into pending status.
Expiration
Transactions will expire if their dependency stays unknown for a defined number of blocks (docs.vechain.org#Expiration (opens in a new tab)).
If expired, the transaction will:
- appear as “stale” transaction
- not cost gas
Unfulfilled Dependency
If the depending transactions is reverted the dependency is unfulfilled. The transactions depending on it are not executed.
The dependent transactions will:
- be removed from the transaction pool
- not appear as failed transaction
- not cost gas
Fulfilled Dependency
A dependency is fulfilled if the transaction becomes known and successfully included into the blockchain.
Dependent transactions are executed in the next block.
The result is identical to:
- a user waiting for a known transaction id to be confirmed on one block
- and submitting a new transaction
Example
Contract
To demonstrate dependencies a test contract was published on the TestNet:
pragma solidity ^0.8.4;
contract TestDependency {
mapping(address => bool) allowedUser;
// reverts if user is not known
function test() public {
require(allowedUser[msg.sender], "Caller is not allowed");
}
// needs to be executed before test() works
function addMyselfToAllowedUser() public {
allowedUser[msg.sender] = true;
}
}
Source Code:\
https://gitlab.com/vechain.energy/examples/contract-transaction-dependency/-/blob/main/contracts/Test.sol (opens in a new tab)
The test()
function requires addMyselfToAllowedUser()
to be run first. A simple example on a transaction depending on another one.
Client
The Sandbox demonstrates how dependency works by calling the test functions with and without dependency.
With dependency
addMyselfToAllowedUser()
is added to the transaction pool and test()
is called with dependsOn
set to the first transaction. To stretch the test window additional four test()
calls are depending on each other.
All transactions are immediately added to the transaction pool when the button is clicked.
With dependency you see that transactions are executed after each other in the next block.
Without dependency
Without dependency the same transactions are submitted immediately as well. All transactions are executed in the same block. Some of these transactions may fail because the order is not enforced to allow the user first.
Sandbox
Sandbox-Link:
https://codesandbox.io/s/transaction-dependency-example-q8p5uf (opens in a new tab)
If you check the blockchain-explorer you will see that future pending transactions are not available until their dependency is actively in processing.
To remove distractions random wallets are generated on each run and fee delegation is used.
ERC20 Example
Another example more true-to-life is this ERC20 example where an approval is required before tokens can be spent:
Sandbox-Link:
https://codesandbox.io/s/transaction-dependency-example-using-erc20-fhsxlc (opens in a new tab)
Read more
Learn more about the backgrounds and details here: