419 lines
10 KiB
Markdown
419 lines
10 KiB
Markdown
|
|
# Blocks and Transactions
|
||
|
|
|
||
|
|
This page covers the general block and transaction CLI tools:
|
||
|
|
|
||
|
|
- `create_transfer_tx`
|
||
|
|
- `broadcast_transaction`
|
||
|
|
- `lookup_block_by_hash`
|
||
|
|
- `lookup_block_by_height`
|
||
|
|
- `lookup_torrent`
|
||
|
|
- `lookup_total_transactions`
|
||
|
|
- `lookup_transaction`
|
||
|
|
|
||
|
|
Most specialized transaction types have their own guides. Token creation and swaps are covered in `TOKEN_SWAPS.md`, NFTs and RWAs are covered in `NFT_TRANSACTIONS.md`, loans are covered in `LOAN_TRANSACTIONS.md`, marketing records are covered in `MARKETING_TRANSACTIONS.md`, and storage transactions are covered in `DATA_STORAGE.md`.
|
||
|
|
|
||
|
|
On Windows, the compiled binaries usually end in `.exe`. For example, `create_transfer_tx` becomes `create_transfer_tx.exe`.
|
||
|
|
|
||
|
|
## Amounts and Raw Values
|
||
|
|
|
||
|
|
Most CLI prompts ask for normal decimal amounts, such as `1`, `1.25`, or `0.0001`.
|
||
|
|
|
||
|
|
Internally, Contractless stores amounts as whole integer units where:
|
||
|
|
|
||
|
|
```text
|
||
|
|
1.00000000 = 100000000
|
||
|
|
```
|
||
|
|
|
||
|
|
That means a transfer entered as `1.25` appears in the saved transaction JSON as:
|
||
|
|
|
||
|
|
```json
|
||
|
|
"value": 125000000
|
||
|
|
```
|
||
|
|
|
||
|
|
The same conversion is used for transaction fees.
|
||
|
|
|
||
|
|
## Signed Transaction Files
|
||
|
|
|
||
|
|
Transaction creation tools write signed transaction files into:
|
||
|
|
|
||
|
|
```text
|
||
|
|
./transactions/
|
||
|
|
```
|
||
|
|
|
||
|
|
The filename is the transaction hash:
|
||
|
|
|
||
|
|
```text
|
||
|
|
./transactions/<transaction_hash>.json
|
||
|
|
```
|
||
|
|
|
||
|
|
The saved JSON often contains a `hash` field. That field is a CLI convenience used for filenames and user display. The on-chain transaction struct is still verified from the signed transaction payload itself.
|
||
|
|
|
||
|
|
## create_transfer_tx
|
||
|
|
|
||
|
|
`create_transfer_tx` creates and signs a transfer transaction.
|
||
|
|
|
||
|
|
Transfers can send:
|
||
|
|
|
||
|
|
- The network base coin.
|
||
|
|
- A fungible token.
|
||
|
|
- A 1-of-1 NFT.
|
||
|
|
- One item from a numbered NFT series.
|
||
|
|
|
||
|
|
The tool saves the signed transaction locally. It does not broadcast it. Use `broadcast_transaction` after reviewing the saved file.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
Interactive:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./create_transfer_tx
|
||
|
|
```
|
||
|
|
|
||
|
|
With command-line fields:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./create_transfer_tx <coin> <value> <receiver> <txfee> <nft_series>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./create_transfer_tx CLTC 10 7ba97ce531937388ef8bca4d8a4ca54cefbefb87.cltc 0.1 0
|
||
|
|
```
|
||
|
|
|
||
|
|
### Fields
|
||
|
|
|
||
|
|
`coin`
|
||
|
|
|
||
|
|
The base coin, token ticker, or NFT asset name to transfer. The base coin is accepted case-insensitively. Non-base assets must normalize to a canonical 3-15 character alphanumeric asset id.
|
||
|
|
|
||
|
|
`value`
|
||
|
|
|
||
|
|
The amount to send, entered in decimal form. For numbered NFT series transfers, this must be exactly `1.0`.
|
||
|
|
|
||
|
|
`receiver`
|
||
|
|
|
||
|
|
The receiving wallet address. The tool accepts a registered short address or vanity address and resolves it to the canonical short address before signing.
|
||
|
|
|
||
|
|
`txfee`
|
||
|
|
|
||
|
|
The transaction fee, entered in decimal form.
|
||
|
|
|
||
|
|
Base coin transfers require a minimum fee of 1% of the transfer amount. Token, NFT, and numbered NFT transfers require the fixed non-base transfer minimum fee.
|
||
|
|
|
||
|
|
`nft_series`
|
||
|
|
|
||
|
|
Use `0` for base coin transfers, token transfers, and 1-of-1 NFTs.
|
||
|
|
|
||
|
|
Use the numbered series item for a collection NFT. For example, if the asset is a numbered NFT and the user wants to transfer item `12`, use:
|
||
|
|
|
||
|
|
```text
|
||
|
|
nft_series = 12
|
||
|
|
```
|
||
|
|
|
||
|
|
### Validation
|
||
|
|
|
||
|
|
The network verifies that:
|
||
|
|
|
||
|
|
- The transaction is not already in the mempool.
|
||
|
|
- The sender and receiver are valid canonical registered short addresses.
|
||
|
|
- The receiver is already registered.
|
||
|
|
- The receiver is not an all-zero burn address.
|
||
|
|
- The sender signature matches the sender wallet.
|
||
|
|
- The asset is the base coin or a canonical padded asset id.
|
||
|
|
- The fee meets the required minimum.
|
||
|
|
- Numbered NFT transfers send exactly one item and the numbered NFT exists.
|
||
|
|
- The sender has enough confirmed plus pending-adjusted balance.
|
||
|
|
- The transaction hash does not already exist on-chain.
|
||
|
|
|
||
|
|
### Example Output
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"txtype": 2,
|
||
|
|
"timestamp": 1783657720,
|
||
|
|
"value": 1000000000,
|
||
|
|
"coin": "CLTC ",
|
||
|
|
"nft_series": 0,
|
||
|
|
"sender": "1439f758f93333734778a6459dc64b8d63a74c06.cltc",
|
||
|
|
"receiver": "7ba97ce531937388ef8bca4d8a4ca54cefbefb87.cltc",
|
||
|
|
"txfee": 10000000,
|
||
|
|
"hash": "8d38f9e9f4f03fb936a6f45e1bcf1a9e706d7f3795e78b7ff16d5b4a4536d73",
|
||
|
|
"signature": "<signature>"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
In this example, `value` is `10.00000000` and `txfee` is `0.10000000`.
|
||
|
|
|
||
|
|
## broadcast_transaction
|
||
|
|
|
||
|
|
`broadcast_transaction` submits a signed transaction JSON file to a configured node.
|
||
|
|
|
||
|
|
This is the common broadcast path for transaction files created by the CLI tools.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./broadcast_transaction <hash.json>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./broadcast_transaction ./transactions/8d38f9e9f4f03fb936a6f45e1bcf1a9e706d7f3795e78b7ff16d5b4a4536d73.json
|
||
|
|
```
|
||
|
|
|
||
|
|
The tool asks for the wallet path and wallet decryption key so it can authenticate to the node. The transaction file itself must already contain the required signature or signatures.
|
||
|
|
|
||
|
|
### Success Output
|
||
|
|
|
||
|
|
```text
|
||
|
|
successful_broadcast: true
|
||
|
|
8d38f9e9f4f03fb936a6f45e1bcf1a9e706d7f3795e78b7ff16d5b4a4536d73
|
||
|
|
```
|
||
|
|
|
||
|
|
If every configured node fails or rejects the transaction, the tool prints the node error or:
|
||
|
|
|
||
|
|
```text
|
||
|
|
failed to connect
|
||
|
|
```
|
||
|
|
|
||
|
|
## lookup_block_by_height
|
||
|
|
|
||
|
|
`lookup_block_by_height` asks a configured node for a block at a specific height.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_block_by_height <block_number>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_block_by_height 31445
|
||
|
|
```
|
||
|
|
|
||
|
|
The tool asks for the wallet path and wallet decryption key for the node handshake. This lookup does not spend funds.
|
||
|
|
|
||
|
|
### Example Return
|
||
|
|
|
||
|
|
The exact transaction list depends on the block contents, but the response is a decoded block JSON object:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"vrf_block": {
|
||
|
|
"unmined_block": {
|
||
|
|
"timestamp": 1783657720,
|
||
|
|
"miner": "1439f758f93333734778a6459dc64b8d63a74c06.cltc",
|
||
|
|
"previous_hash": "<previous_block_hash>",
|
||
|
|
"next_block_difficulty": 1806884765625000,
|
||
|
|
"nonce": 42
|
||
|
|
},
|
||
|
|
"vrf": 123456789,
|
||
|
|
"proof": "<miner_signature_proof>"
|
||
|
|
},
|
||
|
|
"transactions": [
|
||
|
|
{
|
||
|
|
"Rewards": {
|
||
|
|
"unsigned": {
|
||
|
|
"txtype": 1,
|
||
|
|
"timestamp": 1783657720,
|
||
|
|
"value": 41666666666
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
If the node returns a text error, the text is printed directly. If binary data cannot be decoded as a block, the tool prints the raw response as hex JSON.
|
||
|
|
|
||
|
|
## lookup_block_by_hash
|
||
|
|
|
||
|
|
`lookup_block_by_hash` asks a configured node for a block by its block hash.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_block_by_hash <block_hash>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_block_by_hash 8d38f9e9f4f03fb936a6f45e1bcf1a9e706d7f3795e78b7ff16d5b4a4536d73
|
||
|
|
```
|
||
|
|
|
||
|
|
The hash must be 64 hexadecimal characters.
|
||
|
|
|
||
|
|
The returned JSON has the same decoded block shape as `lookup_block_by_height`.
|
||
|
|
|
||
|
|
## lookup_torrent
|
||
|
|
|
||
|
|
`lookup_torrent` asks a configured node for the torrent metadata associated with a block height.
|
||
|
|
|
||
|
|
Blocks and torrents work together in Contractless. The block file contains the block header and transaction payload. The torrent metadata describes how peers can retrieve and verify the block data used during sync and relay.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_torrent <block_number>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_torrent 31445
|
||
|
|
```
|
||
|
|
|
||
|
|
The tool asks for the wallet path and wallet decryption key for the node handshake. This lookup does not spend funds.
|
||
|
|
|
||
|
|
### Example Return
|
||
|
|
|
||
|
|
The exact fields depend on the torrent structure, but a successful response is printed as decoded torrent JSON.
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"announce": "<announce data>",
|
||
|
|
"info": {
|
||
|
|
"name": "31445.block",
|
||
|
|
"piece_length": 16384,
|
||
|
|
"pieces": "<piece hashes>"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
If the torrent is not found, the node may return a text error such as:
|
||
|
|
|
||
|
|
```text
|
||
|
|
error: Block 31445 not found
|
||
|
|
```
|
||
|
|
|
||
|
|
If the response cannot be decoded as a torrent but contains bytes, the tool prints a hex JSON fallback.
|
||
|
|
|
||
|
|
## lookup_total_transactions
|
||
|
|
|
||
|
|
`lookup_total_transactions` asks a configured node for transaction totals grouped by transaction type.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_total_transactions
|
||
|
|
```
|
||
|
|
|
||
|
|
The tool asks for the wallet path and wallet decryption key for the node handshake. This lookup does not spend funds.
|
||
|
|
|
||
|
|
### Example Return
|
||
|
|
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"txtype": 1,
|
||
|
|
"type": "rewards",
|
||
|
|
"total": 31445,
|
||
|
|
"non_zero": 31345
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"txtype": 2,
|
||
|
|
"type": "transfer",
|
||
|
|
"total": 82
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"txtype": 3,
|
||
|
|
"type": "token",
|
||
|
|
"total": 4
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"txtype": 6,
|
||
|
|
"type": "swap",
|
||
|
|
"total": 1
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
For rewards, `total` is the total number of reward transactions and `non_zero` is the number of rewards that paid a non-zero block reward. This lets wallets and explorers show the first 100 free mined blocks while still distinguishing unpaid rewards from paid rewards.
|
||
|
|
|
||
|
|
For other transaction types, only `total` is returned.
|
||
|
|
|
||
|
|
## lookup_transaction
|
||
|
|
|
||
|
|
`lookup_transaction` asks a configured node for one transaction by transaction hash.
|
||
|
|
|
||
|
|
### Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_transaction <transaction_hash>
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_transaction 8d38f9e9f4f03fb936a6f45e1bcf1a9e706d7f3795e78b7ff16d5b4a4536d73
|
||
|
|
```
|
||
|
|
|
||
|
|
The tool asks for the wallet path and wallet decryption key for the node handshake. This lookup does not spend funds.
|
||
|
|
|
||
|
|
### Example Return
|
||
|
|
|
||
|
|
For a transfer transaction, the output looks like:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"block": 4484,
|
||
|
|
"transaction": {
|
||
|
|
"unsigned_transfer": {
|
||
|
|
"txtype": 2,
|
||
|
|
"time": 1782760786,
|
||
|
|
"value": 100000000,
|
||
|
|
"coin": "CLTC ",
|
||
|
|
"nft_series": 0,
|
||
|
|
"sender": "7ba97ce531937388ef8bca4d8a4ca54cefbefb87.cltc",
|
||
|
|
"receiver": "1439f758f93333734778a6459dc64b8d63a74c06.cltc",
|
||
|
|
"txfee": 1000000
|
||
|
|
},
|
||
|
|
"signature": "<signature>"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
`block` is the confirmed block height where the transaction was found.
|
||
|
|
|
||
|
|
`transaction` contains the decoded transaction struct. The inner field name depends on the transaction type, such as `unsigned_transfer`, `unsigned_create_token`, `unsigned_nft`, `unsigned_swap`, `unsigned_loan_contract`, or another transaction-specific payload.
|
||
|
|
|
||
|
|
If the transaction is not found, the node may return a plain text error such as:
|
||
|
|
|
||
|
|
```text
|
||
|
|
Transaction not found in mempool.
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Workflow
|
||
|
|
|
||
|
|
A normal transfer flow is:
|
||
|
|
|
||
|
|
1. Create the signed transaction.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./create_transfer_tx
|
||
|
|
```
|
||
|
|
|
||
|
|
2. Review the saved JSON in `./transactions/`.
|
||
|
|
|
||
|
|
3. Broadcast the signed file.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./broadcast_transaction ./transactions/<transaction_hash>.json
|
||
|
|
```
|
||
|
|
|
||
|
|
4. Look up the transaction after it is submitted or confirmed.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_transaction <transaction_hash>
|
||
|
|
```
|
||
|
|
|
||
|
|
5. Look up the block after the transaction is confirmed.
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./lookup_block_by_height <block_number>
|
||
|
|
```
|