pub struct Transaction<'a, P: JsonRpcProvider + 'static> {
pub network: Option<&'a RpcClient<P>>,
pub version: u8,
pub nonce: u32,
pub valid_until_block: u32,
pub signers: Vec<Signer>,
pub size: i32,
pub sys_fee: i64,
pub net_fee: i64,
pub attributes: Vec<TransactionAttribute>,
pub script: Bytes,
pub witnesses: Vec<Witness>,
/* private fields */
}
Expand description
A Neo N3 blockchain transaction.
The Transaction
struct represents a transaction on the Neo N3 blockchain. It contains
all the necessary information for a transaction, including version, nonce, validity period,
signers, fees, attributes, script, and witnesses.
§Fields
network
- An optional reference to an RPC client for network operations.version
- The transaction version.nonce
- A random number to prevent transaction duplication.valid_until_block
- The block height until which the transaction is valid.signers
- A list of transaction signers.size
- The size of the transaction in bytes.sys_fee
- The system fee for the transaction.net_fee
- The network fee for the transaction.attributes
- Transaction attributes.script
- The transaction script.witnesses
- Transaction witnesses (signatures).block_count_when_sent
- The block count when the transaction was sent.
§Examples
use neo3::neo_builder::{Transaction, TransactionBuilder};
use neo3::neo_clients::{HttpProvider, RpcClient};
fn example() -> Result<(), Box<dyn std::error::Error>> {
// Create a new transaction (placeholder)
// let tx = Transaction::new();
// Transactions are typically created using the TransactionBuilder
let provider = HttpProvider::new("https://testnet1.neo.org:443")?;
let client = RpcClient::new(provider);
// let mut tx_builder = TransactionBuilder::with_client(&client);
Ok(())
}
Fields§
§network: Option<&'a RpcClient<P>>
§version: u8
§nonce: u32
§valid_until_block: u32
§signers: Vec<Signer>
§size: i32
§sys_fee: i64
§net_fee: i64
§attributes: Vec<TransactionAttribute>
§script: Bytes
§witnesses: Vec<Witness>
Implementations§
Source§impl<'a, P: JsonRpcProvider + 'static> Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Transaction<'a, P>
pub fn network(&self) -> &Option<&'a RpcClient<P>>
pub fn version(&self) -> &u8
pub fn nonce(&self) -> &u32
pub fn valid_until_block(&self) -> &u32
pub fn signers(&self) -> &Vec<Signer>
pub fn size(&self) -> &i32
pub fn sys_fee(&self) -> &i64
pub fn net_fee(&self) -> &i64
pub fn attributes(&self) -> &Vec<TransactionAttribute>
pub fn script(&self) -> &Bytes
pub fn witnesses(&self) -> &Vec<Witness>
Source§impl<'a, P: JsonRpcProvider + 'static> Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Transaction<'a, P>
pub fn set_network(&mut self, val: Option<&'a RpcClient<P>>) -> &mut Self
pub fn set_version(&mut self, val: u8) -> &mut Self
pub fn set_nonce(&mut self, val: u32) -> &mut Self
pub fn set_valid_until_block(&mut self, val: u32) -> &mut Self
pub fn set_signers(&mut self, val: Vec<Signer>) -> &mut Self
pub fn set_size(&mut self, val: i32) -> &mut Self
pub fn set_sys_fee(&mut self, val: i64) -> &mut Self
pub fn set_net_fee(&mut self, val: i64) -> &mut Self
pub fn set_attributes(&mut self, val: Vec<TransactionAttribute>) -> &mut Self
pub fn set_script(&mut self, val: Bytes) -> &mut Self
pub fn set_witnesses(&mut self, val: Vec<Witness>) -> &mut Self
Source§impl<'a, T: JsonRpcProvider + 'static> Transaction<'a, T>
impl<'a, T: JsonRpcProvider + 'static> Transaction<'a, T>
pub fn new() -> Self
Sourcepub fn pay<K: Into<NameOrAddress>, V: Into<U256>>(_to: K, _value: V) -> Self
pub fn pay<K: Into<NameOrAddress>, V: Into<U256>>(_to: K, _value: V) -> Self
Convenience function for sending a new payment transaction to the receiver.
pub fn add_witness(&mut self, witness: Witness)
pub async fn get_hash_data(&self) -> Result<Bytes, TransactionError>
Sourcepub async fn send_tx(&mut self) -> Result<RawTransaction, TransactionError>
pub async fn send_tx(&mut self) -> Result<RawTransaction, TransactionError>
Sends the transaction to the Neo N3 network.
This method validates the transaction, converts it to a hexadecimal string, and sends it to the network using the RPC client. It also records the current block count for transaction tracking purposes.
§Returns
A Result
containing the RawTransaction
response if successful,
or a TransactionError
if an error occurs.
§Errors
Returns an error if:
- The number of signers does not match the number of witnesses
- The transaction exceeds the maximum transaction size
- The network client encounters an error when sending the transaction
§Examples
use neo3::neo_builder::{ScriptBuilder, AccountSigner, TransactionBuilder, CallFlags};
use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
use neo3::neo_protocol::{Account, AccountTrait};
use neo3::neo_types::{Address, ContractParameter, ScriptHash, AddressExtension};
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to Neo N3 TestNet
let provider = HttpProvider::new("https://testnet1.neo.org:443").unwrap();
let client = RpcClient::new(provider);
// Load your account from WIF or keystore
let private_key = "your_private_key_here";
let account = Account::from_wif(private_key)?;
// Create a token transfer transaction
let from_address = account.get_address();
let to_address = "NdUL5oDPD159KeFpD5A9zw5xNF1xLX6nLT";
let amount = 1_000_000; // 1 GAS (with 8 decimals)
let mut script_builder = ScriptBuilder::new();
let script = script_builder.contract_call(
&ScriptHash::from_str("d2a4cff31913016155e38e474a2c06d08be276cf")?, // GAS token
"transfer",
&[
ContractParameter::from(account.get_script_hash()),
ContractParameter::from(Address::from_str(to_address)?.address_to_script_hash()?),
ContractParameter::integer(amount),
ContractParameter::any()
],
Some(CallFlags::All)
)?;
// Build the transaction with proper fee calculation
let mut tx_builder = TransactionBuilder::with_client(&client);
tx_builder.extend_script(script.to_bytes());
let account_signer = AccountSigner::called_by_entry(&account)?;
tx_builder.set_signers(vec![account_signer.into()])?;
tx_builder.valid_until_block(client.get_block_count().await? + 2400)?; // ~1 hour validity
// Sign the transaction and get signed transaction
let signed_transaction = tx_builder.sign().await?;
// Send the transaction to the network
let mut transaction = signed_transaction;
let response = transaction.send_tx().await?;
println!("✅ Transaction sent successfully!");
println!("Transaction ID: {}", response.hash);
println!("Transferred {} GAS to {}", amount as f64 / 100_000_000.0, to_address);
Ok(())
}
Sourcepub async fn track_tx(&self, max_blocks: u32) -> Result<(), TransactionError>
pub async fn track_tx(&self, max_blocks: u32) -> Result<(), TransactionError>
Tracks a transaction until it appears in a block.
This method waits for the transaction to be included in a block by monitoring new blocks as they are added to the blockchain. It returns when the transaction is found in a block.
§Arguments
max_blocks
- The maximum number of blocks to wait for the transaction to appear
§Returns
Ok(())
- If the transaction is found in a blockErr(TransactionError)
- If the transaction is not found after waiting formax_blocks
blocks
§Errors
Returns an error if:
- The transaction has not been sent yet
- The maximum number of blocks is reached without finding the transaction
- There is an error communicating with the blockchain
§Examples
use neo3::neo_builder::{ScriptBuilder, AccountSigner, TransactionBuilder, CallFlags};
use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
use neo3::neo_protocol::{Account, AccountTrait};
use neo3::neo_types::{ContractParameter, ScriptHash};
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize provider and client
let provider = HttpProvider::new("https://testnet1.neo.org:443").unwrap();
let client = RpcClient::new(provider);
// Load account and create smart contract deployment transaction
let account = Account::from_wif("your_private_key_here")?;
// Load contract NEF and manifest
let nef_bytes = std::fs::read("path/to/contract.nef")?;
let manifest_bytes = std::fs::read("path/to/contract.manifest.json")?;
let mut script_builder = ScriptBuilder::new();
let deploy_script = script_builder.contract_call(
&ScriptHash::from_str("0xfffdc93764dbaddd97c48f252a53ea4643faa3fd")?, // ContractManagement
"deploy",
&[
ContractParameter::byte_array(nef_bytes),
ContractParameter::byte_array(manifest_bytes),
ContractParameter::any() // Optional data parameter
],
Some(CallFlags::All)
)?;
// Build transaction with appropriate settings for contract deployment
let mut tx_builder = TransactionBuilder::with_client(&client);
tx_builder.extend_script(deploy_script.to_bytes());
let account_signer = AccountSigner::called_by_entry(&account)?;
tx_builder.set_signers(vec![account_signer.into()])?;
tx_builder.valid_until_block(client.get_block_count().await? + 2400)?;
// Sign the transaction and get signed transaction
let signed_transaction = tx_builder.sign().await?;
// Send the transaction
let mut transaction = signed_transaction;
let response = transaction.send_tx().await?;
println!("✅ Contract deployment transaction sent!");
println!("Transaction ID: {}", response.hash);
// Track the transaction until confirmation
println!("⏳ Waiting for transaction confirmation...");
transaction.track_tx(15).await?; // Wait up to 15 blocks (~15 seconds)
println!("🎉 Contract deployment confirmed!");
Ok(())
}
Sourcepub async fn get_application_log<P>(
&self,
provider: &P,
) -> Result<ApplicationLog, TransactionError>where
P: APITrait,
pub async fn get_application_log<P>(
&self,
provider: &P,
) -> Result<ApplicationLog, TransactionError>where
P: APITrait,
Retrieves the application log for this transaction.
Application logs contain detailed information about the execution of a transaction, including notifications, stack items, and any exceptions that occurred during execution.
§Arguments
provider
- A provider implementing theAPITrait
to make the RPC call.
§Returns
A Result
containing the ApplicationLog
if successful,
or a TransactionError
if an error occurs.
§Errors
Returns an error if:
- The transaction has not been sent yet
- The transaction ID cannot be calculated
- The provider encounters an error when retrieving the application log
§Examples
use neo3::neo_builder::{ScriptBuilder, AccountSigner, TransactionBuilder, CallFlags};
use neo3::neo_clients::{HttpProvider, RpcClient, APITrait};
use neo3::neo_protocol::{Account, AccountTrait};
use neo3::neo_types::{ContractParameter, ScriptHash};
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Setup client connection
let provider = HttpProvider::new("https://testnet1.neo.org:443").unwrap();
let client = RpcClient::new(provider);
// Load account for contract interaction
let account = Account::from_wif("your_private_key_here")?;
let contract_hash = ScriptHash::from_str("your_contract_hash_here")?;
// Create a contract invocation transaction
let mut script_builder = ScriptBuilder::new();
let invoke_script = script_builder.contract_call(
&contract_hash,
"setValue", // Contract method name
&[
ContractParameter::string("myKey".to_string()),
ContractParameter::string("myValue".to_string()),
ContractParameter::integer(42)
],
Some(CallFlags::All)
)?;
// Build and configure the transaction
let mut tx_builder = TransactionBuilder::with_client(&client);
tx_builder.extend_script(invoke_script.to_bytes());
let account_signer = AccountSigner::called_by_entry(&account)?;
tx_builder.set_signers(vec![account_signer.into()])?;
tx_builder.valid_until_block(client.get_block_count().await? + 1200)?; // 20 minutes validity
// Sign the transaction and get signed transaction
let signed_transaction = tx_builder.sign().await?;
// Send the transaction
let mut transaction = signed_transaction;
let response = transaction.send_tx().await?;
println!("📤 Smart contract invocation sent!");
println!("Transaction ID: {}", response.hash);
// Wait for confirmation and get detailed execution results
println!("⏳ Waiting for transaction confirmation...");
transaction.track_tx(12).await?;
println!("✅ Transaction confirmed!");
// Analyze the execution results
let app_log = transaction.get_application_log(&client).await?;
println!("🔍 Transaction execution analysis:");
if let Ok(execution) = app_log.get_first_execution() {
println!(" Execution state: {:?}", execution.state);
println!(" GAS consumed: {}", execution.gas_consumed);
// Process contract notifications and events
if !execution.notifications.is_empty() {
println!("📋 Contract notifications:");
for (i, notification) in execution.notifications.iter().enumerate() {
println!(" {}. Event: {} from contract {}",
i + 1, notification.event_name, notification.contract);
println!(" State: {:?}", notification.state);
}
}
// Check execution stack for return values
if !execution.stack.is_empty() {
println!("📊 Return values: {:?}", execution.stack);
}
if execution.state.to_string() == "HALT" {
println!("🎉 Smart contract executed successfully!");
} else {
println!("❌ Smart contract execution failed");
if let Some(exception) = &execution.exception {
println!(" Exception: {}", exception);
}
}
}
Ok(())
}
Trait Implementations§
Source§impl<'a, P: Clone + JsonRpcProvider + 'static> Clone for Transaction<'a, P>
impl<'a, P: Clone + JsonRpcProvider + 'static> Clone for Transaction<'a, P>
Source§fn clone(&self) -> Transaction<'a, P>
fn clone(&self) -> Transaction<'a, P>
1.0.0 · Source§const fn clone_from(&mut self, source: &Self)
const fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<'a, P: Debug + JsonRpcProvider + 'static> Debug for Transaction<'a, P>
impl<'a, P: Debug + JsonRpcProvider + 'static> Debug for Transaction<'a, P>
Source§impl<'a, P: JsonRpcProvider + 'static> Default for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Default for Transaction<'a, P>
Source§impl<'de, 'a, P: JsonRpcProvider + 'static> Deserialize<'de> for Transaction<'a, P>
impl<'de, 'a, P: JsonRpcProvider + 'static> Deserialize<'de> for Transaction<'a, P>
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<'a, P: JsonRpcProvider + 'static> Hash for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Hash for Transaction<'a, P>
Source§impl<'a, P: JsonRpcProvider + 'static> NeoSerializable for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> NeoSerializable for Transaction<'a, P>
Source§impl<'a, P: JsonRpcProvider + 'static> PartialEq for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> PartialEq for Transaction<'a, P>
Source§impl<'a, P: JsonRpcProvider + 'static> Serialize for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Serialize for Transaction<'a, P>
impl<'a, P: JsonRpcProvider + 'static> Eq for Transaction<'a, P>
Auto Trait Implementations§
impl<'a, P> Freeze for Transaction<'a, P>
impl<'a, P> !RefUnwindSafe for Transaction<'a, P>
impl<'a, P> Send for Transaction<'a, P>
impl<'a, P> Sync for Transaction<'a, P>
impl<'a, P> Unpin for Transaction<'a, P>
impl<'a, P> !UnwindSafe for Transaction<'a, P>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more