Comment on page
Signature
A
Signature
is a specific message embedded in a generated proof that will be checked when verifying the proof. It can be requested from the Data Vault via a SignatureRequest.
The signed message is not mandatory when you interact with your contracts, but it is very often needed. As far as your users are generating valid proofs, it could be quite easy for a third party to front-run them by just taking their proof and making their own call to your smart contracts with it.
To overcome this issue, we offer a way to embed a specific message in a proof. This way it can be thought of as a signature since this proof could not be valid without checking successfully that the signed message is correct onchain.
For example, it is mandatory to request the user to embed the address where they want to receive an airdrop in a proof. If a third party takes the proof, the call will be reverted with a signature mismatch message, effectively protecting your users from being front-run.
Example: You are a DAO voting platform, and you want to get the vote of a user onchain. To do so, the user will create a signature containing a message (his vote) that will be used to generate the proof. When verifying the proof onchain, you are also verifying that the proof contains the message. It is then impossible for a malicious actor to take your proof and vote for something else.
The
SignatureRequest
is an object with the following properties:message
(required): the message that the user is going to sign.isSelectableByUser
(optional): by default set tofalse
. Allows the user to edit the message in the Sismo Data Vault app.
// Types (typescript version)
type SignatureRequest = {
message: string;
isSelectableByUser?: boolean;
};
SignatureRequest
is made in the front end using either the sismo-connect-react
package or the sismo-connect-client
package.The proof with the requested signature is then verified either in a backend using the
sismo-connect-server
package or in a smart contract using the sismo-connect-solidity
package.Making an
SignatureRequest
is only possible if it is made alongside an auth or a claim request. React Component
React Hook
TypeScript
The
SismoConnectButton
React component is available from the sismo-connect-react package. It is a wrapper of the sismo-connect-client package. - SignatureRequest is passed to the
SismoConnectButton
through thesignature
props - Responses are received through either:
- 1.the
onResponse: (response: SismoConnectResponse) => void
callback for offchain verification or, - 2.the
onResponseBytes (response: string) => void
callback for onchain verification.
app.tsx
import { SismoConnectButton, SismoConnectClientConfig, SismoConnectResponse, AuthType } from "@sismo-core/sismo-connect-react";
<SismoConnectButton
// the client config created
config={config}
// signature request must be made with at least an auth or one claim
auth={{authType: AuthType.VAULT}}
// your signature request
// that needs to be encoded if you verify proofs in smart contracts
signature={{message: "0x00"}}
onResponse={async (response: SismoConnectResponse) => {
//Send the response to your server to verify it
//thanks to the @sismo-core/sismo-connect-server package
}}
onResponseBytes={async (bytes: string) => {
//Send the response to your contract to verify it
//thanks to the @sismo-core/sismo-connect-solidity package
}}
/>
The
useSismoConnect
hook is available from the sismo-connect-react package. It is a wrapper of the sismo-connect-client package. The useSismoConnect
hook exposes the sismoConnect
variable. - One or multiple claim requests can be made using the
sismoConnect.request()
method available on thesismoConnect
variable. - Responses could be received through either:
- 1.the
sismoConnect.getResponse()
method for offchain verification or, - 2.the
sismoConnect.getResponseBytes()
method for onchain verification.
App.tsx
import { useSismoConnect, SismoConnectResponse, AuthType } from "@sismo-core/sismo-connect-react";
const { sismoConnect } = useSismoConnect({ config });
function onClick(){
sismoConnect.request({
// signature request must be made with at least an auth or one claim
auth: {authType: AuthType.VAULT};
// your signature request
// that needs to be encoded if you verify proofs in smart contracts
signature: {message: "0x00"}
});
}
// Proofs are available in two differents types depending on usage (offchain or onchaon verification)
const response: SismoConnectResponse | null = sismoConnect.getResponse();
const responseBytes: string | null = sismoConnect.getResponseBytes();
if(response || responseBytes) {
// Send response to the backend to verify it or,
// Send responseBytes to smart contract to verify it.
}
- One or multiple ClaimRequests can be made using the
sismoConnect.request()
method available on aSismoConnect
instance. - Responses could be received through either:
- 1.the
sismoConnect.getResponse()
method for offchain verification or, - 2.the
sismoConnect.getResponseBytes()
method for onchain verification.
app.ts
import { SismoConnect, SismoConnectResponse, AuthType } from "@sismo-core/sismo-connect-client";
const sismoConnect = SismoConnect({config});
// your signature request
function onClick(){
sismoConnect.request({
// signature request must be made with at least an auth or one claim
auth: {authType: AuthType.VAULT};
// your signature request
// that needs to be encoded if you verify proofs in smart contracts
signature: {message: "0x00"}
});
}
// Receive the proofs in two different formats
const response: SismoConnectResponse | null = sismoConnect.getResponse();
const responseBytes: string | null = sismoConnect.getResponseBytes();
if(response || responseBytes) {
// Send response to the backend to verify it or,
// Send responseBytes to smart contract to verify it.
}
Once a user has generated the proof on the Sismo Data Vault App, your application must verify it. This can be made either offchain in your back end or onchain in your smart contract. The
sismo-connect-server
package exposes a SismoConnect
variable.Offchain verification - Node.js
Onchain verification - Solidity
A signature request can be verified offchain on a backend server using the
sismoConnect.verify()
method available on a SismoConnect
instance.If the proof is valid
sismoConnect.verify()
returns a result
of type SismoConnectVerifiedResult
else it will throw an error.import { SismoConnect, SismoConnectVerifiedResult, AuthType } from "@sismo-core/sismo-connect-server";
const sismoConnect = SismoConnect({config});
async function verifyResponse(sismoConnectResponse: SismoConnectResponse) {
// verifies the proofs contained in the sismoConnectResponse
const result: SismoConnectVerifiedResult = await sismoConnect.verify(
sismoConnectResponse,
{
// signature request must be made with at least an auth or one claim
auth: { authType: AuthType.VAULT },
// your signature request
signature: {message: "0x00"}
}
)
}
If you are using Nextjs, you will need to add this config in the
next.config.js
file to be able to verify the proof. You can find more information here./** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
serverComponentsExternalPackages: ["@sismo-core/sismo-connect-server"],
},
}
module.exports = nextConfig
The
sismo-connect-solidity
package exposes a Sismo Connect Library, which can be inherited by your contract either using Foundry or Hardhat. The Sismo Connect Library exposes:
- a
verify()
function, which allows you to verify a proof generated by the Sismo Vault app with respect to some requests directly in your contract. The verify() function takes an object containing:- 1.a
responseBytes
send from the front end, - 2.a signature corresponding to the signature request made in the front end,
- 3.an auth or a claim.
contract MyContract is SismoConnect { // inherits from Sismo Connect library
// call SismoConnect constructor with your appId
constructor(bytes16 appId) SismoConnect(buildConfig(appId)) {}
function doSomethingUsingSismoConnect(bytes memory sismoConnectResponse) public {
SismoConnectVerifiedResult memory result = verify({
responseBytes: sismoConnectResponse,
// signature request must be made with at least an auth or one claim
auth: buildAuth({authType: AuthType.VAULT}),
// we want to check if the signed message provided in the response is the signature of the user's address
signature: buildSignature({message: abi.encode(msg.sender)})
});
// do something once verified
}
}
Last modified 3mo ago