Overview
String is a contiguous growable array type containing bytes, stored in the Host and available to contracts through a well-defined API.
Soroban String does not enforce any particular encoding (like UTF-8). It simply stores bytes that can represent text in any encoding.
Creating Strings
from_str()
Creates a String from a Rust string slice.
pub fn from_str(env: &Env, s: &str) -> String
Example:
let msg = String::from_str(&env, "Hello, Soroban!");
from_bytes()
Creates a String from raw bytes.
pub fn from_bytes(env: &Env, b: &[u8]) -> String
Example:
let bytes = [72, 101, 108, 108, 111]; // "Hello" in ASCII
let s = String::from_bytes(&env, &bytes);
Query Methods
len()
Returns the number of bytes in the String.
Example:
let s = String::from_str(&env, "Hello");
assert_eq!(s.len(), 5);
is_empty()
Returns true if the String is empty.
pub fn is_empty(&self) -> bool
Example:
let s = String::from_str(&env, "");
assert!(s.is_empty());
Copying Data
copy_into_slice()
Copies the String bytes into the given slice.
pub fn copy_into_slice(&self, slice: &mut [u8])
Panics:
If the output slice and string are of different lengths.
Example:
let s = String::from_str(&env, "Hello");
let mut output = [0u8; 5];
s.copy_into_slice(&mut output);
assert_eq!(&output, b"Hello");
Conversion
to_bytes()
Converts the String into a Bytes object.
pub fn to_bytes(&self) -> Bytes
Example:
let s = String::from_str(&env, "Hello");
let b: Bytes = s.to_bytes();
assert_eq!(b.len(), 5);
From Bytes
Convert a Bytes object into a String.
let b = bytes!(&env, [72, 101, 108, 108, 111]);
let s: String = b.into();
Display (Non-Wasm only)
to_string()
Converts to a Rust String for display purposes.
let s = String::from_str(&env, "Hello");
let rust_string = s.to_string();
assert_eq!(rust_string, "Hello");
This method is only available in non-Wasm environments (e.g., tests) and will panic if the bytes are not valid UTF-8.
Internal Methods
env()
Returns a reference to the Env.
pub fn env(&self) -> &Env
as_val() / to_val()
Convert to/from Val representation.
pub fn as_val(&self) -> &Val
pub fn to_val(&self) -> Val
as_object() / to_object()
Convert to/from StringObject representation.
pub fn as_object(&self) -> &StringObject
pub fn to_object(&self) -> StringObject
Traits
String implements:
Clone
Debug
Eq, PartialEq
Ord, PartialOrd
Display (non-Wasm only)
TryFromVal<Env, &str>
Examples
Basic String Operations
use soroban_sdk::{Env, String};
let env = Env::default();
// Create from string literal
let greeting = String::from_str(&env, "Hello, Soroban!");
// Check length
assert_eq!(greeting.len(), 15);
assert!(!greeting.is_empty());
// Copy to buffer
let mut buffer = [0u8; 15];
greeting.copy_into_slice(&mut buffer);
Converting Between String and Bytes
use soroban_sdk::{Bytes, Env, String, bytes};
let env = Env::default();
// String to Bytes
let s = String::from_str(&env, "hello");
let b: Bytes = s.to_bytes();
// Bytes to String
let b2 = bytes!(&env, [104, 101, 108, 108, 111]);
let s2: String = b2.into();
assert_eq!(s, s2);
Using String in Storage
use soroban_sdk::{contract, contractimpl, symbol_short, Env, String};
#[contract]
pub struct MetadataContract;
#[contractimpl]
impl MetadataContract {
pub fn set_name(env: Env, name: String) {
env.storage().instance().set(&symbol_short!("name"), &name);
}
pub fn get_name(env: Env) -> String {
env.storage()
.instance()
.get(&symbol_short!("name"))
.unwrap_or(String::from_str(&env, "Unnamed"))
}
}
pub fn process_message(env: Env, message: String) {
// String can be passed directly as a contract argument
if message.is_empty() {
panic!("Message cannot be empty");
}
env.storage().instance().set(&symbol_short!("msg"), &message);
}
Working with Binary Data as String
use soroban_sdk::{Env, String};
let env = Env::default();
// String can contain any bytes, not just valid UTF-8
let binary_data = [0xFF, 0xFE, 0xFD, 0xFC];
let s = String::from_bytes(&env, &binary_data);
assert_eq!(s.len(), 4);
let mut output = [0u8; 4];
s.copy_into_slice(&mut output);
assert_eq!(output, binary_data);
Best Practices
-
Use String for text data: While String doesn’t enforce encoding, it’s semantically meant for text.
-
Use Bytes for binary data: If you’re working with hashes, signatures, or other binary data, use
Bytes or BytesN instead.
-
Be mindful of encoding: Soroban String doesn’t validate UTF-8 or any encoding. If you need UTF-8 guarantees, validate separately.
-
Prefer
from_str() for literals: When creating from string literals, use from_str():
// Good
let s = String::from_str(&env, "hello");
// Unnecessary
let s = String::from_bytes(&env, b"hello");
- Use conversion methods: Convert between String and Bytes as needed:
// String → Bytes
let bytes = string.to_bytes();
// Bytes → String
let string: String = bytes.into();