Перейти к основному содержимому

Создание и отправка транзакций

TransactionBuilder предоставляет fluent API для создания, подписи и отправки транзакций в Savitri Network.

Простой перевод

use savitri_sdk::{Wallet, TransactionBuilder, RpcClient};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = RpcClient::from_url("http://localhost:8545")?;
let wallet = Wallet::from_private_key_hex("your_private_key_hex")?;

// Get current nonce
let nonce = client.get_nonce(wallet.address()).await?;

// Build and sign
let signed_tx = TransactionBuilder::new()
.to("recipient_address_64hex")
.value(1_000_000_000_000_000_000) // 1 SAVT (18 decimals)
.nonce(nonce)
.fee(1_000_000_000_000_000) // 0.001 SAVT fee
.build_and_sign(&wallet)?;

// Submit
let result = client.send_raw_transaction(&serialize_tx(&signed_tx)).await?;
println!("TX hash: {}", result.tx_hash);

Ok(())
}

Builder API

Обязательные поля

МетодТипОписание
.from(address)StringАдрес отправителя (автоматически берётся из кошелька, если не указан)
.to(address)StringАдрес получателя
.value(amount)u128Сумма перевода в минимальных единицах

Необязательные поля

МетодТипПо умолчаниюОписание
.nonce(n)u640Nonce транзакции (получите через get_nonce())
.fee(f)u128NoneКомиссия транзакции
.data(bytes)Vec<u8>NoneДанные для вызовов контрактов

Создание без подписи

let unsigned = TransactionBuilder::new()
.from("sender_address")
.to("recipient_address")
.value(1000)
.nonce(5)
.build()?;

// unsigned.from, unsigned.to, unsigned.value, unsigned.nonce, unsigned.fee, unsigned.data

Создание с подписью

let signed = TransactionBuilder::new()
.to("recipient_address")
.value(1000)
.nonce(5)
.fee(100)
.build_and_sign(&wallet)?;

// signed.transaction -- the UnsignedTransaction
// signed.public_key -- 32-byte ed25519 public key
// signed.signature -- 64-byte ed25519 signature

Если .from() не вызван, автоматически используется адрес кошелька.

Вызовы оракула

let signed = TransactionBuilder::new()
.oracle_call(
"oracle_contract_address",
"request_data",
b"temperature_sensor_01",
)
.value(0)
.nonce(nonce)
.build_and_sign(&wallet)?;

Вызовы управления

Голосование по предложению

use savitri_sdk::GovernanceAction;

let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id, // u64
GovernanceAction::Vote(true), // true = support, false = oppose
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Выполнение одобренного предложения

let signed = TransactionBuilder::new()
.governance_call(
"governance_contract_address",
proposal_id,
GovernanceAction::Execute,
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Создание предложения FL

let signed = TransactionBuilder::new()
.create_fl_proposal(
"governance_contract_address",
"Upgrade model v2", // title
"Replace BERT with GPT-4", // description
604800, // voting period in seconds (7 days)
)
.nonce(nonce)
.build_and_sign(&wallet)?;

Формат подписи транзакции

Сообщение для подписи формируется следующим образом:

from_hex_bytes || to_hex_bytes || amount_le_u64 || nonce_le_u64 || fee_le_u128

Затем хэшируется SHA-256, и хэш подписывается Ed25519.

Этот формат соответствует серверной проверке в savitri-rpc.

Суммы и десятичные знаки

Все суммы используют 18 десятичных знаков:

Человекочитаемая суммаЧисловое значение
1 SAVT1_000_000_000_000_000_000
0.1 SAVT100_000_000_000_000_000
0.001 SAVT1_000_000_000_000_000
0.00001 SAVT10_000_000_000_000

Справочник комиссий

Тип транзакцииКомиссия (SAVT)Числовое значение
Обычный перевод0.0011_000_000_000_000_000
Вызов контракта0.0055_000_000_000_000_000
Данные IoT0.0000550_000_000_000_000