Skip to content
On this page

Strings and bytes

Strings

The SmartPy type sp.string represents strings. Characters are restricted to the printable subset of 7-bit ASCII.

String literals are written in quotes; for example, "abc" is a literal of type sp.string.

Both strings and bytes can be concatenated with +, as in "ab" + "c" == "abc".

sp.slice(offset: sp.nat, length: sp.nat, s: sp.string) → sp.option[sp.string]

Extracts a substring from s, starting at offset (0 referring to the first character) and of length length and returns an option type. If the result is in bounds, the result is wrapped in sp.Some, otherwise None is returned.

For example, sp.slice(3, 5, "0123456789") == sp.Some("34567") and sp.slice(3, 5, "01234") == None.

sp.concat(xs: sp.list[sp.string]) → sp.string

sp.concat concatenates a list of strings, for example:

smartpy
assert sp.concat(["ab", "cd", "ef"]) == "abcdef"

Bytes

The type sp.bytes represents sequences of bytes.

Byte literals are written in hexadecimal notation; for example, sp.bytes("0x100a") refers to a two-byte sequence.

sp.slice(offset: sp.nat, length: sp.nat, s: sp.bytes) → sp.option[sp.bytes]

Extracts a subsequence of bytes from s, starting at offset (0 referring to the first character) and of length length. If the result is in bounds, the result is wrapped in sp.Some, otherwise None is returned.

For example sp.slice(3, 5, sp.bytes("0x00010203040506070809")) == sp.Some(sp.bytes("0x0304050607")) and sp.slice(3, 5, sp.bytes("0x0001020304")) == None.

sp.concat(xs: sp.list[sp.bytes]) → sp.bytes

sp.concat concatenates a list of sp.bytes, for example:

smartpy
assert sp.concat([sp.bytes("0xab"), sp.bytes("0xcd")]) == sp.bytes("0xabcd")

Bitwise logic

As of the Mumbai protocol upgrade, bitwise and, or, and xor operations are available as sp.and_bytes, sp.or_bytes, and sp.xor_bytes on sp.bytes:

sp.and_bytes(x: sp.bytes, y: sp.bytes) → sp.bytes
sp.or_bytes(x: sp.bytes, y: sp.bytes) → sp.bytes
sp.xor_bytes(x: sp.bytes, y: sp.bytes) → sp.bytes

Performs the bitwise logical operations "and", "or", and "xor", respectively, on the arguments x and y, for example:

smartpy
assert sp.and_bytes(sp.bytes("0x2a"), sp.bytes("0x01")) == sp.bytes("0x00")
assert sp.or_bytes(sp.bytes("0x2a"), sp.bytes("0x01")) == sp.bytes("0x2b")
assert sp.xor_bytes(sp.bytes("0x2a"), sp.bytes("0x01")) == sp.bytes("0x2b")
sp.invert_bytes(x: sp.bytes) → sp.bytes

Computes the two's complement of x.

Shifting

Left and right shifts are also available as sp.lshift_bytes and sp.rshift_bytes on sp.bytes:

sp.lshift_bytes(x: sp.bytes, n: sp.nat) → sp.bytes

sp.lshift_bytes shifts x to the left by a given amount n, for example:

smartpy
assert sp.lshift_bytes(sp.bytes("0x2a"), sp.bytes("0x01")) == sp.bytes("0x54")
sp.rshift_bytes(x: sp.bytes, n: sp.nat) → sp.bytes

sp.rshift_bytes shifts x to the right by a given amount n, for example:

smartpy
assert sp.rshift_bytes(sp.bytes("0x2a"), sp.bytes("0x01")) == sp.bytes("0x15")

Packing and unpacking

Packing is how Tezos serializes values and code to a sequence of bytes in an sp.bytes value. For example, contract code is serialized when not in use to save space.

Packing and unpacking is also used to run operations on data, such as computing the hash of a Michelson value by packing it and then running a hash function.

sp.pack(t) → sp.bytes

Packs a value, which obtains its sp.bytes representation.

The type t must be packable, which means that it doesn't involve big maps, operations, sapling states, or tickets.

sp.unpack(x: sp.bytes, t) → sp.option[t]

Unpacks the sp.bytes representation x, assuming it represents a value of type t. Returns None if x does not represent a value of type t.

For more information about packing and unpacking data, see Serialization on docs.tezos.com.