Module snapps_txn_reference_impl::call_data[][src]

Expand description

Opaque data encoding the data passed into and returned from snapp smart contracts.

The format of this data is opaque to the Mina protocol, and is defined by each individual smart contract. This data is unused by the transaction logic.

This data can be used to communicate between snapp smart contracts in a ‘caller/callee’ model.

A ‘caller’ snapp smart contract is able to ‘view’ the call_data field of its ‘callees’ by walking into its crate::call_stack data structure. It will often be useful to model this data as a hash of some arguments to a snapp function and a return value, for example

{ arguments: [Fp], results: [Fp] }

where arguments and results are encoded as as field elements in a fashion defined by the contract.

Motivation

A snapp smart contract that is executed by another snapp smart contract may be thought of as a function

fn do_something(arg1: ..., arg2: ..., ...) -> (result_type1, result_type2, ...)

In this model, it can be beneficial to pass arguments or return values without explicitly exposing them on chain:

  • A snapp may take some private data as its input, which should not be exposed to the chain.
  • A snapp may return some private data in its output, which should not be exposed to the chain.
  • A snapp may take or return some data that is not publically useful, and wants to avoid the additional cost of submitting this data inside the transaction.

This data can be bundled into the call_data using a hash or other encoding, for example by checking that

call_data = hash({arguments, results})

in both the caller and callee smart contracts when using the encoding above.

Examples

Returning private data from a snapp smart contract

A ‘knowledge’ snapp smart contract could store a value commitment in its app_state that ‘commits’ to some known secret value using a hash function:

app_state[0] = hash(secret_random_value, secret_data)

secret_random_value is a fixed number chosen randomly, so that an adversary cannot ‘guess and check’ the value of secret_data by comparing hashes: the chances of them choosing the correct secret_random_value is roughly 1 in 2^254, comparable to randomly choosing the same atom twice out of all atoms in the entire known universe!

This smart contract can then return some value derived from the secret data by checking that secret_data matches, and then setting call_data to the desired value, e.g.

assert_eq!(hash(secret_random_value, secret_data), app_state[0]);
let returned_secret_data = do_something_with(secret_data);
party.call_data = hash(different_random_value, returned_secret_data);

Note that again we use a random value different_random_value to avoid revealing the private data to any parties, even if it were easy to guess on its own (e.g. either 0 or 1).

The calling smart contract can confirm that this value was returned by checking the callee’s party, and then use the data:

assert_eq!(hash(different_random_value, returned_secret_data), called_party.call_data);
do_something_else_with(returned_secret_data)
Bundling together arguments and return values

An ‘addition’ snapp smart contract could accept 2 values as its arguments and return their sum with the first value in its app_state, by storing all of the data together in call_data. For example, in the addition snapp:

fn addition_snapp(party: Party, input1: Fp, input2: Fp) -> (Party, Fp) {
    let output = input1 + input2 + app_state[0];
    party.call_data = hash(input1, input2, output);
    (party, output)
}

and then in the calling snapp:

let called_party, output = call_snapp(addition_snapp, input1, input2);
assert_eq!(hash(input1, input2, output), called_party.call_data)

(The details of call_snapp are left to supporting libraries such as SnarkyJS.)

Structs

Opaque data for communicating between a snapp smart contract and its caller(s). See crate::call_data for more.