在 StakeWise 上质押 ETH(以太坊流动性质押),用于质押、解除质押或查询 StakeWise V3 金库的仓位。
刺杀Ethrewise Ethrewum Swaking Switch. 刺杀V3并获得Oseth(液体吸附物). 刺杀Ethlewy在保持你Eth的液体的同时是一项面向实际任务的技能,主要用于Take Eth – 接收 ~。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。
执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
在 StakeWise V3 上质押 ETH,获得 osETH(流动性质押代币)。在保持 ETH 流动性的同时赚取质押奖励。
请设置以下环境变量,或直接编辑脚本文件:
export STAKEWISE_VAULT="0x8A93A876912c9F03F88Bc9114847cf5b63c89f56" export KEEPER="0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5" export PRIVATE_KEY="your_private_key" export MY_ADDRESS="your_address" export RPC_URL="https://ethereum-rpc.publicnode.com"
# 质押 0.1 ETH(自动处理状态更新) node scripts/stake.mjs 0.1 # 查询已质押仓位 node scripts/position.js # 赎回 0.05 osETH node scripts/unstake.js 0.05 # 检查是否需要状态更新 node scripts/check-state.js
StakeWise V3 使用 keeper-oracle 模式 进行状态更新:
User (EOA/UP)
↓
Vault Contract
↓
Keeper (Oracle) - 验证并处理奖励
↓
osETH Token - 流动性质押代币
| 组件 | 地址 | 用途 |
|---|---|---|
| Vault | 0x8A93A876912c9F03F88Bc9114847cf5b63c89f56 |
质押/赎回逻辑 |
| Keeper | 0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5 |
用于状态更新的 Oracle |
| osETH Token | 按金库动态生成 | 流动性质押代币 |
| Subgraph | https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod |
提供收获证明(harvest proofs)及相关数据 |
为何需要状态更新?
何时需要状态更新?
const vault = new ethers.Contract(vaultAddress, vaultAbi, provider); const needsUpdate = await vault.isStateUpdateRequired(); // 返回 true 表示必须先更新状态,再执行存款
步骤 1:检查状态
用户
↓
vault.isStateUpdateRequired()
↓
返回:true(需更新)
步骤 2:向子图查询收获参数
用户
↓
向 StakeWise 子图发起 POST 请求
↓
返回:rewardsRoot、reward、unlockedMevReward、proof[]
步骤 3:更新状态并存款
用户
↓
vault.updateStateAndDeposit(harvestParams, receiver, referrer)
↓
Keeper 验证收获结果
↓
Vault 向 receiver 铸造 osETH
↓
用户收到 osETH
import { ethers } from 'ethers';
import fetch from 'node-fetch';
// 初始化
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Vault ABI(最小化定义)
const VAULT_ABI = [
'function isStateUpdateRequired() view returns (bool)',
'function updateStateAndDeposit(tuple(bytes32 rewardsRoot, uint256 reward, uint256 unlockedMevReward, bytes32[] proof) harvestParams, address receiver, address referrer) external payable',
'function deposit(address receiver, address referrer) external payable'
];
const vault = new ethers.Contract(
process.env.STAKEWISE_VAULT,
VAULT_ABI,
wallet
);
// 质押金额
const stakeAmount = ethers.parseEther('0.1'); // 0.1 ETH
// 步骤 1:检查是否需要状态更新
const needsUpdate = await vault.isStateUpdateRequired();
console.log('状态更新是否必需:', needsUpdate);
if (needsUpdate) {
// 步骤 2:向子图查询收获参数
const subgraphQuery = {
query: `
query getHarvestProofs($vault: String!) {
harvestProofs(
where: { vault: $vault }
orderBy: blockNumber
orderDirection: desc
first: 1
) {
rewardsRoot
reward
unlockedMevReward
proof
}
}
`,
variables: {
vault: process.env.STAKEWISE_VAULT.toLowerCase()
}
};
const response = await fetch('https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subgraphQuery)
});
const data = await response.json();
const harvestProof = data.data.harvestProofs[0];
// 步骤 3:调用 updateStateAndDeposit
const harvestParams = {
rewardsRoot: harvestProof.rewardsRoot,
reward: BigInt(harvestProof.reward),
unlockedMevReward: BigInt(harvestProof.unlockedMevReward),
proof: harvestProof.proof
};
const tx = await vault.updateStateAndDeposit(
harvestParams,
process.env.MY_ADDRESS, // 接收方
ethers.ZeroAddress, // 推荐人(可选)
{ value: stakeAmount }
);
const receipt = await tx.wait();
console.log(`已质押 ${ethers.formatEther(stakeAmount)} ETH,并完成状态更新`);
console.log(`交易哈希:${receipt.hash}`);
} else {
// 简单存款(无需状态更新)
const tx = await vault.deposit(
process.env.MY_ADDRESS,
ethers.ZeroAddress,
{ value: stakeAmount }
);
const receipt = await tx.wait();
console.log(`已质押 ${ethers.formatEther(stakeAmount)} ETH`);
console.log(`交易哈希:${receipt.hash}`);
}
const OSETH_ABI = [
'function balanceOf(address) view returns (uint256)',
'function convertToAssets(uint256 shares) view returns (uint256)'
];
// 从 Vault 获取 osETH 代币地址
const osEthAddress = await vault.osToken();
const osEth = new ethers.Contract(osEthAddress, OSETH_ABI, provider);
const osEthBalance = await osEth.balanceOf(process.env.MY_ADDRESS);
const underlyingEth = await osEth.convertToAssets(osEthBalance);
console.log(`osETH 余额:${ethers.formatEther(osEthBalance)}`);
console.log(`等价 ETH:${ethers.formatEther(underlyingEth)}`);
const VAULT_FULL_ABI = [
'function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)',
'function maxRedeem(address owner) view returns (uint256)'
];
const vaultFull = new ethers.Contract(
process.env.STAKEWISE_VAULT,
VAULT_FULL_ABI,
wallet
);
// 查询最大可赎回份额
const maxShares = await vaultFull.maxRedeem(process.env.MY_ADDRESS);
console.log(`最大可赎回 osETH:${ethers.formatEther(maxShares)}`);
// 赎回指定份额
const sharesToRedeem = ethers.parseEther('0.05');
const tx = await vaultFull.redeem(
sharesToRedeem,
process.env.MY_ADDRESS, // 接收方
process.env.MY_ADDRESS // 所有者
);
const receipt = await tx.wait();
console.log(`已赎回 ${ethers.formatEther(sharesToRedeem)} osETH,换得 ETH`);
console.log(`交易哈希:${receipt.hash}`);
const query = {
query: `
query {
harvestProofs(
orderBy: blockNumber
orderDirection: desc
first: 1
) {
id
vault
rewardsRoot
reward
unlockedMevReward
proof
blockNumber
}
}
`
};
const response = await fetch('https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(query)
});
const data = await response.json();
console.log(data.data.harvestProofs[0]);
const query = {
query: `
query {
vaults(first: 1) {
id
address
totalAssets
totalShares
apr
}
}
`
};
updateStateAndDeposit() 替代 deposit()osETH.balanceOf(yourAddress)vault.paused() 检查状态0x8A93A876912c9F03F88Bc9114847cf5b63c89f560x6B5815467da09DaA7DC83Db21c9239d98Bb487b5相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.6万人学习
最新文章