Crate stdtx[][src]

Expand description

Extensible schema-driven builder, signer, and Amino serializer for Cosmos SDK-formatted StdTx transactions, the standard transaction format used by the Cosmos SDK and other Tendermint blockchains which use types from the Cosmos SDK.

Uses a TOML-based schema description language for sdk.Msg values which should be encoded into the final StdTx.

Includes a StdTx builder capable of constructing sdk.Msg values and signing them using any ECDSA secp256k1 signer compatible with the ecdsa crate (e.g. signatory-secp256k1, yubihsm).

Equivalent Go code


Below is a self-contained example of how to use stdtx::Builder type to construct a signed [StdTx] message:

use stdtx::{amino::Builder, error::Result};
use k256::ecdsa::SigningKey;
use rand_core::OsRng; // requires `std` feature of `rand_core`

/// Example account number
const ACCOUNT_NUMBER: u64 = 946827;

/// Example chain ID
const CHAIN_ID: &str = "columbus-3";

/// Example oracle feeder for `oracle/MsgExchangeRateVote`
const FEEDER: &str = "terra1t9et8wjeh8d0ewf4lldchterxsmhpcgg5auy47";

/// Example oracle validator for `oracle/MsgExchangeRateVote`
const VALIDATOR: &str = "terravaloper1grgelyng2v6v3t8z87wu3sxgt9m5s03x2mfyu7";

/// Example amount of gas to include in transaction
const GAS_AMOUNT: u64 = 200000;

/// Example StdTx message schema definition. See docs for the
/// `stdtx::Schema` type for more information:
/// <>
/// Message types taken from Terra's oracle voter transactions:
/// <>
pub const TERRA_SCHEMA: &str = r#"
    namespace = "core/StdTx"
    acc_prefix = "terra"
    val_prefix = "terravaloper"

    type_name = "oracle/MsgExchangeRatePrevote"
    fields = [
        { name = "hash",  type = "string" },
        { name = "denom", type = "string" },
        { name = "feeder", type = "sdk.AccAddress" },
        { name = "validator", type = "sdk.ValAddress" },

    type_name = "oracle/MsgExchangeRateVote"
    fields = [
        { name = "exchange_rate", type = "sdk.Dec"},
        { name = "salt", type = "string" },
        { name = "denom", type = "string" },
        { name = "feeder", type = "sdk.AccAddress" },
        { name = "validator", type = "sdk.ValAddress" },

/// Simple builder for an `oracle/MsgExchangeRateVote` message
fn build_vote_msg(schema: &stdtx::amino::Schema) -> Result<stdtx::amino::Msg> {
    Ok(stdtx::amino::msg::Builder::new(schema, "oracle/MsgExchangeRateVote")?
        .decimal("exchange_rate", -1i8)?
        .string("salt", "XXXX")?
        .string("denom", "ukrw")?
        .acc_address_bech32("feeder", FEEDER)?
        .val_address_bech32("validator", VALIDATOR)?

/// Parse the TOML schema for Terra `sdk.Msg` types
let schema = TERRA_SCHEMA.parse::<stdtx::amino::Schema>().unwrap();

/// Create message builder, giving it an account number, chain ID, and a
/// boxed ECDSA secp256k1 signer
let builder = stdtx::amino::Builder::new(schema, CHAIN_ID, ACCOUNT_NUMBER);

/// Create ECDSA signing key (ordinarily you wouldn't generate a random key
/// every time but reuse an existing one)
let signer = SigningKey::random(&mut OsRng);

/// Create message to be included in the `StdTx` using the method defined above
let msg = build_vote_msg(builder.schema()).unwrap();

/// Build transaction, returning serialized Amino bytes as a `Vec<u8>`
let sequence_number = 123456;
let fee = stdtx::amino::StdFee::for_gas(GAS_AMOUNT);
let memo = "";
let amino_bytes = builder
    .sign_amino_tx(&signer, sequence_number, fee, memo, &[msg])

// `amino_bytes` is now a `Vec<u8>` containing an Amino serialized transaction


pub use self::address::Address;
pub use self::decimal::Decimal;
pub use self::error::Error;


Address types (account or validator)

Amino encoding support.

Decimal type providing equivalent semantics to Cosmos sdk.Dec

Error types


ECDSA/secp256k1 verification key (i.e. public key)

Type Definitions

ECDSA/secp256k1 signature (fixed-size)

Transaction signer for ECDSA/secp256k1 signatures