How it works?
vlayer introduces new super powers to Solidity smart contracts:
- Time Travel: Execute a smart contract on historical data.
- Teleport: Execute a smart contract across different blockchain networks.
- Web proof: Access verified web content, including APIs and websites.
- Email proof: Access verified email content.
Prover and Verifier
To implement the above features, vlayer introduces two new contract types: Prover
and Verifier
.
The Prover
code runs on the vlayer zkEVM infrastructure. Proof data structure is the result of this operation.
The Verifier
verifies generated proof and runs your code on EVM-compatible chains.
Both types of contracts are developed using the Solidity programming language.
vlayer contract execution
A typical vlayer execution flow has three steps:
- The application initiates a call to the Prover contract that is executed off-chain in the zkEVM. All the input for this call is private by default and is not published on-chain.
- The result of the computation is passed along with a proof to be executed in the on-chain contract. All the output returned from Prover contract is public and is published on-chain as parameters to the Verifier contract.
- The Verifier contract verifies the data sent by the proving party (using the submitted proof by client) and then executes the Verifier code.
See the diagram below.
The flow of vlayer contract execution
Prover
vlayer Prover contracts have a few distinct properties:
- verifiability - can be executed off-chain and results can't be forged.
- privacy - inputs are private by default and are not published on-chain.
- no gas fees - no usual transaction size limits apply.
All arguments passed to the Prover contract functions are private by default. To make an argument public, simply add it to the list of returned values.
See the example Prover contract code below. It generates proof of ownership of the BYAC (Bored Ape Yacht Club) NFT.
contract BoredApeOwnership is Prover {
function main(address _owner, uint256 _apeId) public returns (Proof, address) {
// jumps to block 12292922 at ETH mainnet (chainId=1), when BYAC where minted
setChainId(1, 12292922);
require(IERC721(BYAC_NFT_ADDR).ownerOf(_apeId) == _owner, "Given address not owning that BYAC");
return (proof(), _owner);
}
}
In order to access Prover specific features, your contract needs to derive from the vlayer Prover contract. Then setChainId()
teleport context to a historic block at Ethereum Mainnet (chainId=1
) in which the first mint of BYAC NFT occurred. require
makes sure that the given address (_owner
) was the owner of the specific _apeId
at that point of time. The owner address, which makes it public input for the Verifier contract.
Verifier
The Verifier smart contract validates the correctness of a computation generated by Prover, without revealing the underlying information. Such contracts can be used to facilitate more complex workflows, such as privacy-preserving decentralized finance (DeFi) applications or confidential voting systems.
Verification logic is immutable once deployed on the blockchain, ensuring consistent and permissionless access.
See the example Verifer
contract below. It transfers tokens to proven owner of certain NFT:
contract Airdrop is Verifier {
function claim(Proof calldata _p, address owner)
public
onlyVerified(PROVER_VLAYER_CONTRACT_ADDR, NftOwnership.main.selector)
{
IERC20(TOKEN_ADDR).transfer(owner, 1000);
}
}
Note that the above contract inherits from the Verfier
vlayer contract.
It is necessary for veryfing the computation done by the Prover contract from the previous step.
claim()
function takes proof returned by the vlayer SDK as the first argument. Other arguments are public inputs returned from Prover main()
function (in the same order).
onlyVerified(address, bytes4)
modifier ensures that proof is valid and takes two arguments:
- Address of the Prover contract
- Function selector of the Prover main function
Proof
doesn't have to be passed to onlyVerified
as an argument. However, it has to be passed as an argument to function that is being decorated with onlyVerified
, along with the public outputs.
To learn more about how the Prover and Verifier work under the hood, please refer to our Advanced section.