public void ShouldSerializeMerkleNodeCorrectly() { MerkleNode merkleNode = new MerkleNode { Size = 8, Name = "My Merkle Node", Hash = new MultiHash("QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o"), Data= Encoding.UTF8.GetBytes("My string"), Links = null, }; string actual = _jsonSerializer.Serialize(merkleNode); string expected = "{\"Data\":\"TXkgc3RyaW5n\",\"Hash\":\"QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o\",\"Links\":null,\"Name\":\"My Merkle Node\",\"Size\":8}"; Assert.IsTrue(Equals(actual, expected)); }
/// <summary> /// Stores input as a DAG object, outputs its key /// 'ipfs object put' is a plumbing command for storing DAG nodes. /// It reads from stdin, and the output is a base58 encoded multihash. /// </summary> /// <param name="node">Node to be stored as a DAG object</param> /// <returns>The added object key</returns> public async Task<MerkleNode> Put(MerkleNode node) { var flags = new Dictionary<string, string>(); flags.Add("encoding", GetIpfsEncodingValue(IpfsEncoding.Json)); flags.Add("datafieldenc", GetIpfsEncodingValue(IpfsEncoding.Base64)); //Thanks to @slothbag for this snippet MultipartFormDataContent content = new MultipartFormDataContent(); string json = _jsonSerializer.Serialize(node); StringContent sc = new StringContent(json); sc.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(sc, "file", "file"); HttpContent returnContent = await ExecutePostAsync("put", flags, content); string returnJson = await returnContent.ReadAsStringAsync(); return _jsonSerializer.Deserialize<MerkleNode>(returnJson); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { MerkleNode merkleNode = new MerkleNode(); int startingDepth = reader.Depth; while (!(reader.TokenType == JsonToken.EndObject && startingDepth == reader.Depth)) { reader.Read(); if (reader.TokenType == JsonToken.PropertyName) { string propertyName = reader.Value.ToString(); if (String.Equals(propertyName, "Data")) { reader.Read(); merkleNode.Data = serializer.Deserialize<byte[]>(reader); } else if (String.Equals(propertyName, "Hash")) { reader.Read(); merkleNode.Hash = serializer.Deserialize<MultiHash>(reader); } else if (String.Equals(propertyName, "Links")) { reader.Read(); merkleNode.Links = serializer.Deserialize<IEnumerable<MerkleNode>>(reader); } else if (String.Equals(propertyName, "Name")) { reader.Read(); merkleNode.Name = serializer.Deserialize<string>(reader); } else if (String.Equals(propertyName, "Size")) { reader.Read(); merkleNode.Size = serializer.Deserialize<long?>(reader); } } } return merkleNode; }
public override void Init(ZCashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, BitcoinNetworkType networkType, bool isPoS, double shareMultiplier, decimal?blockrewardMultiplier, IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher)); Contract.RequiresNonNull(headerHasher, nameof(headerHasher)); Contract.RequiresNonNull(blockHasher, nameof(blockHasher)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.poolConfig = poolConfig; this.clusterConfig = clusterConfig; this.clock = clock; this.poolAddressDestination = poolAddressDestination; this.networkType = networkType; if (ZCashConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx)) { coinbaseTx.TryGetValue(networkType, out chainConfig); } BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double)new BigRational(chainConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().ToBigInteger()); this.isPoS = isPoS; this.shareMultiplier = shareMultiplier; this.headerHasher = headerHasher; this.blockHasher = blockHasher; this.equihash = chainConfig.Solver(); if (!string.IsNullOrEmpty(BlockTemplate.Target)) { blockTargetValue = new uint256(BlockTemplate.Target); } else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseArray() .ToHexString(); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.TxId.HexToByteArray().ReverseArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray(); merkleRootReversed = merkleRoot.ReverseArray(); merkleRootReversedHex = merkleRootReversed.ToHexString(); jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, BlockTemplate.Height.ReverseByteOrder().ToStringHex8() + sha256Empty.Take(28).ToHexString(), // height + hashReserved BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(), false }; }
public virtual void Init(EquihashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, Network network, EquihashSolver solver) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.RequiresNonNull(solver, nameof(solver)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.clock = clock; this.poolAddressDestination = poolAddressDestination; coin = poolConfig.Template.As <EquihashCoinTemplate>(); networkParams = coin.GetNetwork(network.NetworkType); this.network = network; BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double)new BigRational(networkParams.Diff1BValue, BlockTemplate.Target.HexToReverseByteArray().AsSpan().ToBigInteger()); // ZCash Sapling & Overwinter support isSaplingActive = networkParams.SaplingActivationHeight.HasValue && networkParams.SaplingTxVersion.HasValue && networkParams.SaplingTxVersionGroupId.HasValue && networkParams.SaplingActivationHeight.Value > 0 && blockTemplate.Height >= networkParams.SaplingActivationHeight.Value; isOverwinterActive = isSaplingActive || networkParams.OverwinterTxVersion.HasValue && networkParams.OverwinterTxVersionGroupId.HasValue && networkParams.OverwinterActivationHeight.HasValue && networkParams.OverwinterActivationHeight.Value > 0 && blockTemplate.Height >= networkParams.OverwinterActivationHeight.Value; if (isSaplingActive) { txVersion = networkParams.SaplingTxVersion.Value; txVersionGroupId = networkParams.SaplingTxVersionGroupId.Value; } else if (isOverwinterActive) { txVersion = networkParams.OverwinterTxVersion.Value; txVersionGroupId = networkParams.OverwinterTxVersionGroupId.Value; } // Misc this.solver = solver; if (!string.IsNullOrEmpty(BlockTemplate.Target)) { blockTargetValue = new uint256(BlockTemplate.Target); } else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseInPlace() .ToHexString(); if (blockTemplate.Subsidy != null) { blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin; } else { blockReward = BlockTemplate.CoinbaseValue; } if (networkParams?.vFundingStreams == true) { decimal fundingstreamTotal = 0; fundingstreamTotal = blockTemplate.Subsidy.FundingStreams.Sum(x => x.Value); blockReward = (blockTemplate.Subsidy.Miner + fundingstreamTotal) * BitcoinConstants.SatoshisPerBitcoin; } else if (networkParams?.PayFoundersReward == true) { var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community; if (!founders.HasValue) { throw new Exception("Error, founders reward missing for block template"); } blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin; } rewardFees = blockTemplate.Transactions.Sum(x => x.Fee); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToReverseByteArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseInPlace(); merkleRootReversed = merkleRoot.ReverseInPlace(); merkleRootReversedHex = merkleRootReversed.ToHexString(); // misc var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ? blockTemplate.FinalSaplingRootHash.HexToReverseByteArray().ToHexString() : sha256Empty.ToHexString(); var solutionIn = !string.IsNullOrEmpty(blockTemplate.Solution) ? blockTemplate.Solution.HexToByteArray().ToHexString() : null; jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, hashReserved, BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToReverseByteArray().ToHexString(), false, solutionIn }; }
protected override MerkleNode CreateNode(MerkleNode left, MerkleNode right) { return(new DemoMerkleNode((DemoMerkleNode)left, (DemoMerkleNode)right)); }
private void ComputeMerkleTree(MerkleNode root) { var merkle = new Stack <byte[]>(); ComputeMerkleTree(root, merkle); }
public override void Init(ZCashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, BitcoinNetworkType networkType, bool isPoS, double shareMultiplier, decimal?blockrewardMultiplier, IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher)); Contract.RequiresNonNull(headerHasher, nameof(headerHasher)); Contract.RequiresNonNull(blockHasher, nameof(blockHasher)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.poolConfig = poolConfig; this.clusterConfig = clusterConfig; this.clock = clock; this.poolAddressDestination = poolAddressDestination; this.networkType = networkType; if (ZCashConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var chain)) { chain.TryGetValue(networkType, out chainConfig); } BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double)new BigRational(chainConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().AsSpan().ToBigInteger()); txExpiryHeight = blockTemplate.Height + 100; // ZCash Sapling & Overwinter support isSaplingActive = chainConfig.SaplingActivationHeight.HasValue && chainConfig.SaplingTxVersion.HasValue && chainConfig.SaplingTxVersionGroupId.HasValue && chainConfig.SaplingActivationHeight.Value > 0 && blockTemplate.Height >= chainConfig.SaplingActivationHeight.Value; isOverwinterActive = isSaplingActive || chainConfig.OverwinterTxVersion.HasValue && chainConfig.OverwinterTxVersionGroupId.HasValue && chainConfig.OverwinterActivationHeight.HasValue && chainConfig.OverwinterActivationHeight.Value > 0 && blockTemplate.Height >= chainConfig.OverwinterActivationHeight.Value; if (isSaplingActive) { txVersion = chainConfig.SaplingTxVersion.Value; txVersionGroupId = chainConfig.SaplingTxVersionGroupId.Value; } else if (isOverwinterActive) { txVersion = chainConfig.OverwinterTxVersion.Value; txVersionGroupId = chainConfig.OverwinterTxVersionGroupId.Value; } // Misc this.isPoS = isPoS; this.shareMultiplier = shareMultiplier; this.headerHasher = headerHasher; this.blockHasher = blockHasher; this.equihash = chainConfig.Solver(); if (!string.IsNullOrEmpty(BlockTemplate.Target)) { blockTargetValue = new uint256(BlockTemplate.Target); } else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseArray() .ToHexString(); blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin; if (chainConfig?.PayFoundersReward == true) { var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community; if (!founders.HasValue) { throw new Exception("Error, founders reward missing for block template"); } blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin; } rewardFees = blockTemplate.Transactions.Sum(x => x.Fee); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray(); merkleRootReversed = merkleRoot.ReverseArray(); merkleRootReversedHex = merkleRootReversed.ToHexString(); // misc var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ? blockTemplate.FinalSaplingRootHash.HexToByteArray().ReverseArray().ToHexString() : sha256Empty.ToHexString(); jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, hashReserved, BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(), false }; }
public MerkleNode GetMerkleRoot() { return(MerkleNode.GetRoot(this.Transactions.Select(t => t.GetHash()))); }
public override void Init(ZCashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, XPoolConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, BitcoinNetworkType networkType, bool isPoS, double shareMultiplier, decimal blockrewardMultiplier, IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher) { Assertion.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Assertion.RequiresNonNull(poolConfig, nameof(poolConfig)); Assertion.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Assertion.RequiresNonNull(clock, nameof(clock)); Assertion.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Assertion.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher)); Assertion.RequiresNonNull(headerHasher, nameof(headerHasher)); Assertion.RequiresNonNull(blockHasher, nameof(blockHasher)); Assertion.Requires<ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.poolConfig = poolConfig; this.clusterConfig = clusterConfig; this.clock = clock; this.poolAddressDestination = poolAddressDestination; this.networkType = networkType; if (ZCashConstants.CoinbaseTxConfig.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx)) coinbaseTx.TryGetValue(networkType, out coinbaseTxConfig); BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double) new BigRational(coinbaseTxConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().ToBigInteger()); this.isPoS = isPoS; this.shareMultiplier = shareMultiplier; this.headerHasher = headerHasher; this.blockHasher = blockHasher; if (!string.IsNullOrEmpty(BlockTemplate.Target)) blockTargetValue = new uint256(BlockTemplate.Target); else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseArray() .ToHexString(); blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin; if (coinbaseTxConfig?.PayFoundersReward == true) { var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community; if (!founders.HasValue) throw new Exception("Error, founders reward missing for block template"); blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin; } rewardFees = blockTemplate.Transactions.Sum(x => x.Fee); BuildCoinbase(); var txHashes = new List<uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray()))); merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray(); merkleRootReversed = merkleRoot.ReverseArray(); merkleRootReversedHex = merkleRootReversed.ToHexString(); jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, sha256Empty.ToHexString(), BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(), false }; }
public void VerifyHash() { MerkleNode parent = CreateNode("ae", "lf"); Assert.True(parent.VerifyHash()); }
public void LeftRightHashVerificationTest() { MerkleNode parentNode = CreateParentNode("abc", "def"); Assert.True(parentNode.VerifyHash()); }
public BlockInfo(Block block) { Header = block.Header; MerkleRootNode = block.MerkleRootNode; }
public override void Init(ZCashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, BitcoinNetworkType networkType, bool isPoS, double shareMultiplier, IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher)); Contract.RequiresNonNull(headerHasher, nameof(headerHasher)); Contract.RequiresNonNull(blockHasher, nameof(blockHasher)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.poolConfig = poolConfig; this.clusterConfig = clusterConfig; this.clock = clock; this.poolAddressDestination = poolAddressDestination; this.networkType = networkType; if (ZCashConstants.CoinbaseTxConfig.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx)) { coinbaseTx.TryGetValue(networkType, out coinbaseTxConfig); } BlockTemplate = blockTemplate; JobId = jobId; Difficulty = new Target(new NBitcoin.BouncyCastle.Math.BigInteger(BlockTemplate.Target, 16)).Difficulty; this.isPoS = isPoS; this.shareMultiplier = shareMultiplier; this.headerHasher = headerHasher; this.blockHasher = blockHasher; blockTargetValue = BigInteger.Parse(BlockTemplate.Target, NumberStyles.HexNumber); previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseArray() .ToHexString(); blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin; if (coinbaseTxConfig?.PayFoundersReward == true) { var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community; if (!founders.HasValue) { throw new Exception("Error, founders reward missing for block template"); } blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin; } rewardFees = blockTemplate.Transactions.Sum(x => x.Fee); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray(); merkleRootReversed = merkleRoot.ReverseArray(); merkleRootReversedHex = merkleRootReversed.ToHexString(); }
public void LeftRightHashVerificationTest() { MerkleNode parentNode = CreateParentNode("abc", "def"); parentNode.VerifyHash().Should().BeTrue(); }
public override void Init(EquihashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, Network network, EquihashSolver solver) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.clock = clock; this.poolAddressDestination = poolAddressDestination; coin = poolConfig.Template.As <EquihashCoinTemplate>(); this.network = network; var equihashTemplate = poolConfig.Template.As <EquihashCoinTemplate>(); networkParams = coin.GetNetwork(network.ChainName); BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double)new BigRational(networkParams.Diff1BValue, BlockTemplate.Target.HexToReverseByteArray().AsSpan().ToBigInteger()); this.solver = solver; if (!string.IsNullOrEmpty(BlockTemplate.Target)) { blockTargetValue = new uint256(BlockTemplate.Target); } else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseInPlace() .ToHexString(); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.TxId.HexToReverseByteArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseInPlace(); merkleRootReversed = merkleRoot.ReverseInPlace(); merkleRootReversedHex = merkleRootReversed.ToHexString(); jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, BlockTemplate.Height.ReverseByteOrder().ToStringHex8() + sha256Empty.Take(28).ToHexString(), // height + hashReserved BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToReverseByteArray().ToHexString(), false }; } }
public void SetParent(MerkleNode parentNode) { Parent = parentNode; }