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.