在提交到矿池之前验证 NodeJS 中的挖矿份额Stratum

如何解决在提交到矿池之前验证 NodeJS 中的挖矿份额Stratum

我正在尝试验证份额是否满足最低难度。

我拥有创建区块哈希并进行难度比较所需的所有数据。

我的代码没有生成有效的区块哈希,但不明白为什么。

我的带有示例数据的代码:

const crypto = require('crypto');

sha256 = function(buffer){
    var hash1 = crypto.createHash('sha256');
    hash1.update(buffer);
    return hash1.digest();
};

sha256d = function(buffer){
    return sha256(sha256(buffer));
};

reverseBuffer = function(buff){
    var reversed = new Buffer.alloc(buff.length);
    for (var i = buff.length - 1; i >= 0; i--)
        reversed[buff.length - i - 1] = buff[i];
    return reversed;
};

reverseHex = function(hex){
    return reverseBuffer(Buffer.from(hex,'hex')).toString('hex');
};

serializeCoinbase = function(coinbase1,coinbase2,extraNonce1,extraNonce2){
    var coinbase =  coinbase1+
                    extraNonce1+
                    extraNonce2+
                    coinbase2;
    return Buffer.from(coinbase,'hex');
};

MerkleRootWithCoinbase = function(merkleTree,coinbaseHash){
    var hash = coinbaseHash;
    merkleTree.forEach(a => {
        hash = sha256d(Buffer.from(hash + a,'hex')).toString('hex')
    });
    return hash
}

convertPreviousblockhash = function(previousblockhash){
    return previousblockhash.match(/.{1,8}/g).reverse().join('')
}

blockHeader = function(blockVersion,previousblockhash,merkleRoot,nTime,nBits,nonce){
    previousblockhash = convertPreviousblockhash(previousblockhash)
    var hash =  reverseHex(blockVersion)+
                reverseHex(previousblockhash)+
                reverseHex(merkleRoot)+
                reverseHex(nTime)+
                reverseHex(nBits)+
                reverseHex(nonce);
    return Buffer.from(hash,'hex');
};

// blockTemplate is received from pool (mining.notify)
let blockTemplate =  {
    ExtraNonce1: '929e4bb4',ExtraNonce2_size: 4,previousblockhash: '83ed60ce078736fe15528d3f5ea5cfdd0ed72b04000a31440000000000000000',coinbase: [
    '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5c0332410a192f5669614254432f4d696e6564206279206c6576616d75732f2cfabe6d6def4d71fab9c4856256f87621806274036feb16b79c411157a920716275e722951000000000000000108ad5ef13de0027ea','ffffffff04ce4c6229000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3acac6189d090598816a3e1092b966aad3c6aef15e3c826a334cea7f21002fd6540000000000000000266a24b9e11b6d65ba1a6db71ac060e04c3cb5bf049af5478970ded266f93b2f5b89f86348c9fc0000000000000000266a24aa21a9edf2716abb1dd5ac06ad1fed7f6bde943fc1657a0fd53a1c11823a4ffb5cc823e400000000'
    ],merkleTree: [
    '628a4d82f4950e0d55407f231057e8524a27e724143667cfd6c4bb3bc323d75f','e1ec3b078e79bd6da16899697e47a1eff05f27304baf7bf4fb3784145b452343','dfac6e968c29d40b35f34474b081b3fb9a054497c8ce8cebfca36471e9b5f912','35ea339bda0105cd0401e5f4dd89c511a41ea34117d839d6d3e32b575f4e4dc0','97bd6bfb590b9cb2a6f388f3a4039a926ed0487f82f6215860443a4bef28fe10','3126b182f4115fe6705c36a43737cd38eaf3e600add0de49bd6823c7f0fa6a11','793fa91f40722794f2234fd5ab7904a94432f8376b5cef86e7440a457b3482c4','d1370e331d8752b53e6b07d560a3d0b9f03569e2686e786739e3a96cc2ae7eb8','e99e29d9953dea3642621c08e31bd78ab9a3648b630af7dcff2dd90bdbca08b8','5655477db1423bef022382ccfe88d2c597f64bc69df6f4f520adca95a29f94aa','3c719be7fbeed1101542c6420fde3f4e5fd773284effacf8f9f21e4a05e5d416'
    ],blockVersion: '20000000',nBits: '170cf4e3',nTime: '6036f006'
}

// extraNonce2,nTime and nonce is received from miner (mining.submit)
let extraNonce2 = "301a0000"
let nTime = "6036f00a"
let nonce = "e4abf319"

let coinbaseBuffer = serializeCoinbase(blockTemplate.coinbase[0],blockTemplate.coinbase[1],blockTemplate.ExtraNonce1,extraNonce2);
let coinbaseHash = sha256d(coinbaseBuffer);
console.log(coinbaseHash.toString('hex'))
// result: a97941791004f1ad8fe01d9e1a0116b932e65c37b7de2bd29ebd238c0705aa72

let merkleRoot = MerkleRootWithCoinbase(blockTemplate.merkleTree,coinbaseHash.toString('hex'));
console.log(merkleRoot.toString('hex'))
// result: 7c1a57f3f75d94e3f1014afca791101e80eebed18b3bca014f798e7399f3ceef

let headerBuffer = blockHeader(blockTemplate.blockVersion,blockTemplate.previousblockhash,blockTemplate.nBits,nonce);

console.log(headerBuffer.toString('hex'))
// result: 00000020ce60ed83fe3687073f8d5215ddcfa55e042bd70e44310a000000000000000000efcef399738e794f01ca3b8bd1beee801e1091a7fc4a01f1e3945df7f3571a7c0af03660e3f40c1719f3abe4

let headerHash = sha256d(headerBuffer);
console.log(headerHash.toString('hex'))
// result: 87d83009bcca8068760bbdf5130a19b88e0f120c17cb97590397aed4b62ef4e4

let headerHashReversed = reverseBuffer(headerHash);
console.log(headerHashReversed.toString('hex'))
// result: e4f42eb6d4ae97035997cb170c120f8eb8190a13f5bd0b766880cabc0930d887

结果哈希无效,不明白我哪里有无效计算。

解决方法

如果矿工正在使用版本滚动,则意味着矿工能够按照 BIP320 中的规定操作位 - 在掩码 0x1fffe000 内。 尝试将提交中的版本包含到块哈希计算中。

,

我解决了问题,您可以在下面找到工作示例:

const crypto = require('crypto');

sha256 = function(buffer){
    var hash1 = crypto.createHash('sha256');
    hash1.update(buffer);
    return hash1.digest();
};

sha256d = function(buffer){
    return sha256(sha256(buffer));
};

reverseBuffer = function(buff){
    var reversed = new Buffer.alloc(buff.length);
    for (var i = buff.length - 1; i >= 0; i--)
        reversed[buff.length - i - 1] = buff[i];
    return reversed;
};

reverseHex = function(hex){
    return reverseBuffer(Buffer.from(hex,'hex')).toString('hex');
};

serializeCoinbase = function(coinbase1,coinbase2,extraNonce1,extraNonce2){
    var coinbase =  coinbase1+
                    extraNonce1+
                    extraNonce2+
                    coinbase2;
    return Buffer.from(coinbase,'hex');
};

MerkleRootWithCoinbase = function(merkleTree,coinbaseHash){
    var hash = coinbaseHash;
    merkleTree.forEach(a => {
        hash = sha256d(Buffer.from(hash + a,'hex')).toString('hex')
    });
    return hash
}

convertPreviousblockhash = function(previousblockhash){
    return previousblockhash.match(/.{1,8}/g).reverse().join('')
}

blockHeader = function(blockVersion,previousblockhash,merkleRoot,nTime,nBits,nonce){
    previousblockhash = convertPreviousblockhash(previousblockhash)
    var hash =  reverseHex(blockVersion)+
                reverseHex(previousblockhash)+
                merkleRoot+
                reverseHex(nTime)+
                reverseHex(nBits)+
                reverseHex(nonce);
    return Buffer.from(hash,'hex');
};

// blockTemplate is received from pool (mining.notify)
let blockTemplate =  {
    ExtraNonce1: '929e4bb4',ExtraNonce2_size: 4,previousblockhash: '83ed60ce078736fe15528d3f5ea5cfdd0ed72b04000a31440000000000000000',coinbase: [
    '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5c0332410a192f5669614254432f4d696e6564206279206c6576616d75732f2cfabe6d6def4d71fab9c4856256f87621806274036feb16b79c411157a920716275e722951000000000000000108ad5ef13de0027ea','ffffffff04ce4c6229000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3acac6189d090598816a3e1092b966aad3c6aef15e3c826a334cea7f21002fd6540000000000000000266a24b9e11b6d65ba1a6db71ac060e04c3cb5bf049af5478970ded266f93b2f5b89f86348c9fc0000000000000000266a24aa21a9edf2716abb1dd5ac06ad1fed7f6bde943fc1657a0fd53a1c11823a4ffb5cc823e400000000'
    ],merkleTree: [
    '628a4d82f4950e0d55407f231057e8524a27e724143667cfd6c4bb3bc323d75f','e1ec3b078e79bd6da16899697e47a1eff05f27304baf7bf4fb3784145b452343','dfac6e968c29d40b35f34474b081b3fb9a054497c8ce8cebfca36471e9b5f912','35ea339bda0105cd0401e5f4dd89c511a41ea34117d839d6d3e32b575f4e4dc0','97bd6bfb590b9cb2a6f388f3a4039a926ed0487f82f6215860443a4bef28fe10','3126b182f4115fe6705c36a43737cd38eaf3e600add0de49bd6823c7f0fa6a11','793fa91f40722794f2234fd5ab7904a94432f8376b5cef86e7440a457b3482c4','d1370e331d8752b53e6b07d560a3d0b9f03569e2686e786739e3a96cc2ae7eb8','e99e29d9953dea3642621c08e31bd78ab9a3648b630af7dcff2dd90bdbca08b8','5655477db1423bef022382ccfe88d2c597f64bc69df6f4f520adca95a29f94aa','3c719be7fbeed1101542c6420fde3f4e5fd773284effacf8f9f21e4a05e5d416'
    ],blockVersion: '20000000',nBits: '170cf4e3',nTime: '6036f006'
}

// extraNonce2,nTime and nonce is received from miner (mining.submit)
let extraNonce2 = "301a0000"
let nTime = "6036f00a"
let nonce = "e4abf319"

let coinbaseBuffer = serializeCoinbase(blockTemplate.coinbase[0],blockTemplate.coinbase[1],blockTemplate.ExtraNonce1,extraNonce2);
let coinbaseHash = sha256d(coinbaseBuffer);
console.log(coinbaseHash.toString('hex'))
// result: a97941791004f1ad8fe01d9e1a0116b932e65c37b7de2bd29ebd238c0705aa72

let merkleRoot = MerkleRootWithCoinbase(blockTemplate.merkleTree,coinbaseHash.toString('hex'));
console.log(merkleRoot.toString('hex'))
// result: 7c1a57f3f75d94e3f1014afca791101e80eebed18b3bca014f798e7399f3ceef

let headerBuffer = blockHeader(blockTemplate.blockVersion,blockTemplate.previousblockhash,blockTemplate.nBits,nonce);

console.log(headerBuffer.toString('hex'))
// result: 00000020ce60ed83fe3687073f8d5215ddcfa55e042bd70e44310a0000000000000000007c1a57f3f75d94e3f1014afca791101e80eebed18b3bca014f798e7399f3ceef0af03660e3f40c1719f3abe4

let headerHash = sha256d(headerBuffer);
console.log(headerHash.toString('hex'))
// result: 5edd9d1f993bb74a4f1b5fcd3ab48140df048af0c3bfa43c16c1000000000000

let headerHashReversed = reverseBuffer(headerHash);
console.log(headerHashReversed.toString('hex'))
// result: 000000000000c1163ca4bfc3f08a04df4081b43acd5f1b4f4ab73b991f9ddd5e

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res