EVM Resource Machine Datatypes¶
This section contains the descriptions of the RM datatype implementations and their interfaces.
The "Proof" sections try to describe the explicit implementation details that may differ from the original RM specification.
Resource¶
A resource is implemented as the following Solidity struct:
struct Resource {
    bytes32 logicRef;
    bytes32 labelRef;
    bytes32 valueRef;
    bytes32 nullifierKeyCommitment;
    bytes32 nonce;
    bytes32 randSeed;
    uint128 quantity;
    bool ephemeral;
}
Resource Computable Components¶
- Commitment
- 
A commitment of resource resourceis computed as packed bytes of the resource fields alongside with hardcoded 17 bytes prepending randomness values:
    function commitment(Resource memory resource) internal pure returns (bytes32 cm) {
        cm = sha256(
            abi.encodePacked(
                resource.logicRef,
                resource.labelRef,
                resource.quantity,
                resource.valueRef,
                resource.ephemeral,
                resource.nonce,
                resource.nullifierKeyCommitment,
                rcm(resource)
            )
        );
    }
    function rcm(Resource memory resource) internal pure returns (bytes32 randCm) {
        bytes17 prfExpandPersonalization = 0x52495343305f457870616e645365656401;
        randCm = sha256(abi.encodePacked(prfExpandPersonalization, resource.randSeed, resource.nonce));
    }
- Nullifier
- 
A nullifier of a resource resourcewith nullifier keynullifierKeyis computed as packed bytes of the nullifier key, nonce, hardcoded 17 bytes with randomness fields of a resource, as well as the commitment of a resource as described above.
    function nullifier(Resource memory resource, bytes32 nullifierKey) internal pure returns (bytes32 nf) {
        nf = sha256(abi.encodePacked(nullifierKey, resource.nonce, psi(resource), commitment(resource)));
    }
    function psi(Resource memory resource) internal pure returns (bytes32 randNf) {
        bytes17 prfExpandPersonalization = 0x52495343305f457870616e645365656400;
        randNf = sha256(abi.encodePacked(prfExpandPersonalization, resource.randSeed, resource.nonce));
    }
- Kind
- 
A kind of a resource resourcewithlogicRef = resource.logicRefandlabelRef = resource.labelRefis computed assha256(abi.encode(logicRef, labelRef)).
- Delta
- 
The delta of a resource resourceis computed as the multiple of the resource kind and quantity seen as scalars and Pedersen-committed to a 2D point on the K256 curve. However, we do not use them for verification purposes. For details one can consult the compliance circuit.
Compliance Unit¶
The compliance unit is defined as the VerifierInput struct:
    struct VerifierInput {
        bytes proof;
        Instance instance;
    }
where the instance is the expected compliance unit instance type:
    struct Instance {
        ConsumedRefs consumed;
        CreatedRefs created;
        bytes32 unitDeltaX;
        bytes32 unitDeltaY;
    }
where
    struct ConsumedRefs {
        bytes32 nullifier;
        bytes32 logicRef;
        bytes32 commitmentTreeRoot;
    }
and
    struct CreatedRefs {
        bytes32 commitment;
        bytes32 logicRef;
    }
As mentioned in EVM Primitive Interfaces page, the unit delta is represented as a 2D point.
Action¶
The action datatype is described as
struct Action {
    Logic.VerifierInput[] logicVerifierInputs;
    Compliance.VerifierInput[] complianceVerifierInputs;
}
Where the compliance verifier input time is defined above, while the logic verifier input is defined as:
    struct VerifierInput {
        bytes32 tag;
        bytes32 verifyingKey;
        AppData appData;
        bytes proof;
    }
The AppData stands for the 4 different payloads we posess:
    struct AppData {
        ExpirableBlob[] resourcePayload;
        ExpirableBlob[] discoveryPayload;
        ExpirableBlob[] externalPayload;
        ExpirableBlob[] applicationPayload;
    }
with ExpirableBlob defined as
    struct ExpirableBlob {
        DeletionCriterion deletionCriterion;
        bytes blob;
    }
There are only two deletion criteria we support:
    enum DeletionCriterion {
        Immediately,
        Never
    }
The storage of the criteria is designated to the EVM event history logs. Once the transaction is executed, the event will be transmitted, including the blobs, which will then be recoverable by an interested party through indexing services.
The actionTreeRoot is computed as the root of a merkle tree of depth 4 with leaves provided by the tags in the corresponding Action.
Transaction¶
The transaction is defined as a list of actions with the delta prove attesting to the balancing of the action alongside an aggregation proof, attesting to the verification of all the logic and compliance verifying keys present in the transaction given the instances:
struct Transaction {
    Action[] actions;
    bytes deltaProof;
    bytes aggregationProof;
}
If an aggregation proof is present, the PA only checks the delta and the aggregation proofs.