Contractless/docs/BLOCKS_AND_TRANSACTIONS.md

375 lines
9.1 KiB
Markdown
Raw Normal View History

2026-07-12 19:34:49 +00:00
# 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_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_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>
```