安装 Node.js 20+,新建一个空目录。
LIVE ISSUANCE · ARBITRUM ONEOPEN TO BUILDERS & MINERS
02 Mining guide
Mine openly.
Watch it work.
官网不提供封装后的可执行程序。下面是完整、可检查的 CPU 参考实现,运行时会动态展示 nonce、实时哈希、累计计算量和算力,适用于安装 Node.js 的 Windows、macOS 和 Linux 电脑。
START Three preparations
Inspect before
you execute.
这是 Arbitrum One 主网。请使用专用钱包并只存入可承受损失的少量 ETH。计算在本地完成;找到候选结果后提交交易会产生真实 Gas,竞争失败或回滚也可能消耗 Gas。
npm install ethers dotenv将专用钱包信息保存在本地 .env。
Configuration.env
CROLL_RPC_URL=https://arb1.arbitrum.io/rpc
CROLL_CONTRACT_ADDRESS=0x09C1E372efc31c97d9A0e4574DDe6321f311088e
CROLL_PRIVATE_KEY=0xYOUR_DEDICATED_WALLET_PRIVATE_KEYMAINNET SECURITY
Keep signing local.
私钥不应离开你的设备。不要把 .env 上传到网页、聊天或代码仓库,也不要使用持有大量资产的钱包。运行前请自行检查所有代码。
CPU reference implementationminer.js
const { ethers } = require("ethers");
const { randomBytes } = require("node:crypto");
require("dotenv").config();
const abi = [
"function miningState() view returns (uint256,bytes32,uint256,uint256,uint256,uint256)" ,
"function mine(uint256 nonce)"
];
const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
const sleep = () => new Promise(resolve => setImmediate(resolve));
const short = value => value.slice(0, 18) + "…" + value.slice(-12);
function draw({ frame, epoch, remaining, attempts, started, nonce, proof }) {
const rate = attempts / Math.max((Date.now() - started) / 1000, 0.001);
process.stdout.write("\x1b[2J\x1b[H");
console.log(" COMPUTE ROLL " + frames[frame % frames.length] + " LIVE HASHING");
console.log(" ─────────────────────────────────────────────");
console.log(" Status HASHING");
console.log(" Epoch " + (epoch + 1n) + " / 100000");
console.log(" Remaining " + remaining);
console.log(" Hash rate " + rate.toFixed(0) + " H/s");
console.log(" Attempts " + attempts.toLocaleString() + " hashes");
console.log("");
console.log(" Nonce " + nonce);
console.log(" Live hash " + short(proof));
console.log("");
console.log(" Ctrl+C safely stops local computation");
}
async function main() {
const provider = new ethers.JsonRpcProvider(process.env.CROLL_RPC_URL);
const wallet = new ethers.Wallet(process.env.CROLL_PRIVATE_KEY, provider);
const contract = new ethers.Contract(process.env.CROLL_CONTRACT_ADDRESS, abi, wallet);
const [epoch, challenge, target, , reward, remaining] = await contract.miningState();
let nonce = BigInt("0x" + randomBytes(32).toString("hex"));
let attempts = 0;
let frame = 0;
const started = Date.now();
while (true) {
let proof;
for (let batch = 0; batch < 2048; batch++, nonce++, attempts++) {
proof = ethers.solidityPackedKeccak256(
["bytes32", "address", "uint256"],
[challenge, wallet.address, nonce]
);
if (BigInt(proof) < target) {
process.stdout.write("\x1b[2J\x1b[H");
console.log("CANDIDATE FOUND · nonce " + nonce);
const latest = await contract.miningState();
if (latest[1] !== challenge || latest[2] !== target) return main();
const tx = await contract.mine(nonce);
console.log("Submitted:", tx.hash);
await tx.wait();
console.log("Accepted:", ethers.formatEther(reward), "CROLL");
return main();
}
}
draw({ frame: frame++, epoch, remaining, attempts, started, nonce: nonce.toString(), proof });
await sleep(); // lets the terminal repaint without changing the hash rule
}
}
main().catch(console.error);运行方式
将代码保存为 miner.js,然后在同一目录运行 node miner.js。终端动画只抽样显示哈希,不会逐条打印全部结果,以免输出拖慢计算。代码会在每次链上任务变化后重新读取状态;公开 RPC 可能限流,正式参与可替换为自己的 Arbitrum RPC。
需要验证数据?