Skip to content
On this page

Records

Records in SmartPy are of type sp.record(field1=..., field2=...), for example sp.record(field1=1, field2="A string"), which is of type sp.record(a=sp.int, b=sp.string.

Accessing records

You can access a record's components with dot-notation, as in this example:

smartpy
x = sp.record(a=42, b="abc", c=True)
assert x.a == 42
assert x.b == "abc"
assert x.c == True
x.a = 12
assert x.a == 12

However, you cannot add components to a record or change the type of components after you create it.

Destructuring records

You can destructure a record into individual variables with the record() function. For example, if x is a SmartPy record of type sp.record(a=int, b=int), this code assigns x.a to a new variable a and x.b to a new variable b:

smartpy
x = sp.record(a=sp.int(42), b=sp.int(12))
record(a, b).match = x
assert a == 42
assert b == 12

If the variable name differs from the component name, the parameters must be named, as in this example:

smartpy
x = sp.record(a=sp.int(42), b=sp.int(12))
record(a=y, b=z).match = x
assert y == 42
assert z == 12

Updating records

To change components of a record, use the sp.modify_record() as x function, as in this example:

smartpy
# Create a record
x = sp.record(a=sp.int(42), b=sp.int(12))

# Update the record
with sp.modify_record(x) as r:
    r.a = 1
    r.b = 5

# Verify the changes
assert x.a == 1
assert x.b == 5

This function can be convenient to edit the contract storage fields in place, as in this example:

smartpy
with sp.modify_record(self.data) as data:
    data.x = 12
    data.y += 1
    # ...

The sp.modify_record() as x function tells the SmartPy compiler to open the record, handle its fields independently and recreate the record afterwards in a linear way. It can be useful when dealing with tickets.

See test_ticket.py (ide, download) for examples.

You cannot add fields to a record after creating it.

Layouts

By default, records are compiled to Michelson tuples as right combs. Different layouts can be specified in the type as follows:

.layout(layout)
A record type, i.e. something of the form sp.record(...), can be used to define a record type with a layout by doing:

python
t: type = sp.record(
    owner=sp.address, operator=sp.address, token_id=sp.string
).layout(("owner", ("operator", "token_id")))

Changing the layout does not affect how the fields are accessed in SmartPy, only how they are stored in Michelson.