Snapshot 投票流程
date
Aug 4, 2023
slug
snapshot-simulation
status
Published
tags
ethers.js
summary
type
Post
- 查询当前活跃投票
GraphQL https://hub.snapshot.org/graphql
req:
query Proposals {
proposals(first: 20, skip: 0, where: { space_in: ["lido-snapshot.eth"], state: "active" }, orderBy: "created", orderDirection: desc) {
id
title
body
choices
start
end
snapshot
state
author
type
app
space {
id
name
}
}
}
拿到投票的
id
和 snapshot
.- 查询投票详情
GraphQL https://hub.snapshot.org/graphql
req:
query Proposal($id: String!) {
proposal(id: $id) {
id
ipfs
title
body
discussion
choices
start
end
snapshot
state
author
created
plugins
network
type
quorum
symbol
privacy
validation {
name
params
}
strategies {
name
network
params
}
space {
id
name
}
scores_state
scores
scores_by_strategy
scores_total
votes
flagged
}
}
variables:
{
"id": "<proposal id>"
}
拿到投票的
network
和 strategies
.- 检查是否投过票
GraphQL https://hub.snapshot.org/graphql
req:
query Votes(
$id: String!,
$first: Int,
$skip: Int,
$orderBy: String,
$orderDirection: OrderDirection,
$reason_not: String,
$voter: String,
$space: String,
$created_gte: Int
) {
votes(
first: $first,
skip: $skip,
where: {
proposal: $id,
vp_gt: 0,
voter: $voter,
space: $space,
reason_not: $reason_not,
created_gte: $created_gte
},
orderBy: $orderBy,
orderDirection: $orderDirection
) {
ipfs
voter
choice
vp
vp_by_strategy
reason
created
}
}
variables:
{
"id":"<proposal id>",
"voter":"<your address>"
}
res:
只返回最新一条投票记录,新的投票会顶掉旧的投票。
如果未投过:
{"data":{"votes":[]}}
- 根据
strategies
检查投票权
req:
{
"method":"get_vp",
"params":{
"space":"lido-snapshot.eth",
"delegation":false,
"network":"1",
"snapshot":17834886,
"strategies":[...],
"address":"<your address>"
}
}
res:
{
"jsonrpc": "2.0",
"result": {
"vp": 0,
"vp_by_strategy": [
0,
0
],
"vp_state": "final"
},
"id": null,
"cache": true
}
- 签名 (EIP-712)
const message = {
"domain":{
"name":"snapshot",
"version":"0.1.4"
},
"types":{
"Vote":[
{ name: 'from', type: 'address' },
{ name: 'space', type: 'string' },
{ name: 'timestamp', type: 'uint64' },
{ name: 'proposal', type: 'bytes32' },
{ name: 'choice', type: 'uint32' },
{ name: 'reason', type: 'string' },
{ name: 'app', type: 'string' },
{ name: 'metadata', type: 'string' }
]
},
"message":{
"space":"•8099.eth",
"proposal":"0xf5a5d1339b96c787f1e8ad69655d62c4d22cfdda40bb2e11e6687c22183a81ad",
"choice":1,
"app":"snapshot",
"reason":"",
"metadata":"{}",
"from":"<your address>",
"timestamp":1691163048
}
};
const signer = new ethers.Wallet(PRIVATE_KEY);
const sig = await signer._signTypedData(message.domain, message.types, message.message);
console.log(sig);
拿到哈希
sig
.- 提交投票信息
POST https://seq.snapshot.org/
req:
{
"address":"<your address>",
"sig":"<sig>",
"data": {<第三步中的整个message对象>}
}
res:
{
"id": "",
"ipfs": "",
"relayer": {
"address": "",
"receipt": ""
}
}
可通过返回值中的 IPFS cid v1 验证投票信息,可能需要等待几分钟。
error:
{
"error": "unauthorized",
"error_description": "signature validation failed"
}