/// <summary> /// Get Transaction Merkle Path by height and transactionHash /// </summary> /// <param name="height"></param> /// <param name="transactionHash"></param> /// <returns>IObservable<MerklePath></returns> public IObservable <MerklePath> GetTransactionMerklePath(ulong height, string transactionHash) { var route = $"{BasePath}/block/{height}/transaction/{transactionHash}/merkle"; return(Observable.FromAsync(async ar => await route.GetJsonAsync <MerkleProofInfoDTO>()) .Select(i => MerklePath.FromDto(i))); }
/// <summary> /// Gets receipt merkle path by given block height and recipentHash. /// </summary> /// <param name="height"></param> /// <param name="receiptHash"></param> /// <returns>IObservable<MerklePath></returns> public IObservable <MerklePath> GetReceiptMerklePath(ulong height, string receiptHash) { var route = $"{BasePath}/block/{height}/receipt/{receiptHash}/merkle"; return(Observable.FromAsync(async ar => await route.GetJsonAsync <MerkleProofInfoDTO>()) .Select(i => MerklePath.FromDto(i))); }
private Hash ComputeRootWithTransactionStatusMerklePath(Hash txId, MerklePath path) { var txResultStatusRawBytes = EncodingHelper.EncodeUtf8(TransactionResultStatus.Mined.ToString()); var hash = HashHelper.ComputeFrom(ByteArrayHelper.ConcatArrays(txId.ToByteArray(), txResultStatusRawBytes)); return(path.ComputeRootWithLeafNode(hash)); }
/// <summary> /// Record merkle path of self chain block, which is from parent chain. /// </summary> /// <param name="height"></param> /// <param name="path"></param> private void AddIndexedTxRootMerklePathInParentChain(long height, MerklePath path) { var existing = State.TxRootMerklePathInParentChain[height]; Assert(existing == null, $"Merkle path already bound at height {height}."); State.TxRootMerklePathInParentChain[height] = path; }
private Hash ComputeRootWithTransactionStatusMerklePath(Hash txId, MerklePath path) { var txResultStatusRawBytes = EncodingHelper.GetBytesFromUtf8String(TransactionResultStatus.Mined.ToString()); var hash = Hash.FromRawBytes(txId.ToByteArray().Concat(txResultStatusRawBytes).ToArray()); return(path.ComputeRootWithLeafNode(hash)); }
public async Task <JObject> ProcGetTxMerklePath(string txid) { try { Hash txHash; try { txHash = Hash.LoadHex(txid); } catch (Exception) { throw new Exception("Invalid Address Format"); } var txResult = await this.GetTransactionResult(txHash); if (txResult.Status != Status.Mined) { throw new Exception("Transaction is not mined."); } var merklePath = txResult.MerklePath?.Clone(); if (merklePath == null) { throw new Exception("Not found merkle path for this transaction."); } MerklePath merklePathInParentChain = null; ulong boundParentChainHeight = 0; try { merklePathInParentChain = this.GetTxRootMerklePathInParentChain(txResult.BlockNumber); boundParentChainHeight = this.GetBoundParentChainHeight(txResult.BlockNumber); } catch (Exception e) { throw new Exception("Unable to get merkle path from parent chain"); } /*if(merklePathInParentChain == null) * throw new Exception("Not found merkle path in parent chain");*/ if (merklePathInParentChain != null) { merklePath.Path.AddRange(merklePathInParentChain.Path); } return(new JObject { ["merkle_path"] = merklePath.ToByteArray().ToHex(), ["parent_height"] = boundParentChainHeight }); } catch (Exception e) { return(new JObject { ["error"] = e.Message }); } }
/// <summary> /// Calculate the <see cref="BinaryMerkleTree.Root"/> with path and provided leaf. /// </summary> /// <param name="merklePath"></param> /// <param name="leaf"></param> /// <returns></returns> public static Hash ComputeRootWith(this MerklePath merklePath, Hash leaf) { Hash hash = leaf.Clone(); foreach (var node in merklePath.Path) { hash = BinaryMerkleTree.CalculateRootFromMultiHash(new[] { hash, node }); } return(hash); }
private void AddIndexedTxRootMerklePathInParentChain(ulong height, MerklePath path) { var key = new UInt64Value { Value = height }; Api.Assert(_txRootMerklePathInParentChain.GetValue(key) == null, $"Merkle path already bound at height {height}."); // _txRootMerklePathInParentChain[key] = path; _txRootMerklePathInParentChain.SetValueAsync(key, path).Wait(); Console.WriteLine("Path: {0}", path.Path[0].DumpHex()); }
public bool VerifyTransaction(Hash tx, MerklePath path, ulong parentChainHeight) { var key = new UInt64Value { Value = parentChainHeight }; Api.Assert(_parentChainBlockInfo.GetValue(key) != null, $"Parent chain block at height {parentChainHeight} is not recorded."); var rootCalculated = path.ComputeRootWith(tx); var parentRoot = _parentChainBlockInfo.GetValue(key)?.Root?.SideChainTransactionsRoot; //Api.Assert((parentRoot??Hash.Zero).Equals(rootCalculated), "Transaction verification Failed"); return((parentRoot ?? Hash.Zero).Equals(rootCalculated)); }
private MerklePath GenerateMerklePath(IList <int> index, IList <Hash> hashes) { var merklePath = new MerklePath(); foreach (var i in index) { merklePath.MerklePathNodes.Add(new MerklePathNode { Hash = hashes[i], IsLeftChildNode = i % 2 == 0 }); } return(merklePath); }
public static bool VerifyTransaction(Hash txId, MerklePath merklePath, ulong parentChainHeight) { var scAddress = GetSideChainContractAddress(); if (scAddress == null) { throw new InternalError("No side chain contract was found.\n" + _lastCallContext.Trace.StdErr); } if (Call(scAddress, "VerifyTransaction", ParamsPacker.Pack(txId, merklePath, parentChainHeight))) { return(GetCallResult().DeserializeToPbMessage <BoolValue>().Value); } return(false); }
public MerklePath GenerateMerklePath(int index) { if (Root == null || index >= LeafCount) { throw new InvalidOperationException("Cannot generate merkle path from incomplete binary merkle tree."); } MerklePath path = new MerklePath(); int indexOfFirstNodeInRow = 0; int nodeCountInRow = LeafCount; while (index < Nodes.Count - 1) { Hash neighbor; bool isLeftNeighbor; if (index % 2 == 0) { // add right neighbor node neighbor = Nodes[index + 1]; isLeftNeighbor = false; } else { // add left neighbor node neighbor = Nodes[index - 1]; isLeftNeighbor = true; } path.MerklePathNodes.Add(new MerklePathNode { Hash = Hash.FromByteArray(neighbor.ToByteArray()), IsLeftChildNode = isLeftNeighbor }); nodeCountInRow = nodeCountInRow % 2 == 0 ? nodeCountInRow : nodeCountInRow + 1; int shift = (index - indexOfFirstNodeInRow) / 2; indexOfFirstNodeInRow += nodeCountInRow; index = indexOfFirstNodeInRow + shift; nodeCountInRow /= 2; } return(path); }
public void MerklePathExtensions_ComputeRootWithLeafNode_Test() { // left node { var merkleLeftNode = new MerklePathNode { Hash = HashHelper.ComputeFrom("node1"), IsLeftChildNode = true }; var nodePath = new MerklePath { MerklePathNodes = { merkleLeftNode } }; var hash = HashHelper.ComputeFrom("new"); var calculateHash = nodePath.ComputeRootWithLeafNode(hash); var targetHash = HashHelper.ConcatAndCompute(merkleLeftNode.Hash, hash); calculateHash.ShouldBe(targetHash); } // right node { var merkleLeftNode = new MerklePathNode { Hash = HashHelper.ComputeFrom("node1"), IsLeftChildNode = false }; var nodePath = new MerklePath { MerklePathNodes = { merkleLeftNode } }; var hash = HashHelper.ComputeFrom("new"); var calculateHash = nodePath.ComputeRootWithLeafNode(hash); var targetHash = HashHelper.ConcatAndCompute(hash, merkleLeftNode.Hash); calculateHash.ShouldBe(targetHash); } }
public static Hash ComputeRootWithLeafNode(this MerklePath path, Hash leaf) { return(path.MerklePathNodes.Aggregate(leaf, (current, node) => node.IsLeftChildNode ? HashHelper.ConcatAndCompute(node.Hash, current) : HashHelper.ConcatAndCompute(current, node.Hash))); }
/// <summary> /// Add <see cref="MerklePath"/> for tx root of a block indexed by parent chain. /// </summary> /// <param name="path"></param> /// <param name="chainId">Child chain id</param> /// <param name="height">Child chain height</param> /// <returns></returns> public async Task AddIndexedTxRootMerklePathInParentChain(MerklePath path, Hash chainId, ulong height) { var key = DataPath.CalculatePointerForIndexedTxRootMerklePathByHeight(chainId, height); await _dataStore.InsertAsync(key, path); }
private Hash ComputeMerklePath(Hash leaf, MerklePath path) { return(path.ComputeRootWith(leaf)); }
private void CrossChainVerify(Hash transactionId, long parentChainHeight, int chainId, MerklePath merklePath) { var verificationInput = new VerifyTransactionInput { TransactionId = transactionId, ParentChainHeight = parentChainHeight, VerifiedChainId = chainId, Path = merklePath }; var address = Context.GetContractAddressByName(SmartContractConstants.CrossChainContractSystemName); var verificationResult = Context.Call <BoolValue>(address, nameof(ACS7Container.ACS7ReferenceState.VerifyTransaction), verificationInput); Assert(verificationResult.Value, "Cross chain verification failed."); }
public static MerklePath AddRange(this MerklePath merklePath, IEnumerable <Hash> hashes) { merklePath.Path.AddRange(hashes); return(merklePath); }
private void CrossChainVerify(Hash transactionId, long parentChainHeight, int chainId, MerklePath merklePath) { var verificationInput = new VerifyTransactionInput { TransactionId = transactionId, ParentChainHeight = parentChainHeight, VerifiedChainId = chainId, Path = merklePath }; var verificationResult = GetValidCrossChainContractReferenceState().VerifyTransaction.Call(verificationInput); Assert(verificationResult.Value, "Cross chain verification failed."); }
private Hash ComputeRootWithMerklePathAndLeaf(Hash leaf, MerklePath path) { return(path.ComputeRootWithLeafNode(leaf)); }
public void TestMerklePathFromEth() { var expectedRoot = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x90ae927b3312b71e5ea7c8644a9d6f4e6107bf6c0e06df094c94be16d8023c52")); { var hex = "0x324144584c63794b4d47477252653961474337584d584543763863787a33546f73317a36504a4853667958677553615662350000000000000000000000000000000000000000000000001111d67bb1bb0000"; var expectedHash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0xa80afe5c85c3e9b09e8c74070d5d8d4de60780968d78e7b031e939e7335b6916")); var actualHash = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(hex)); Assert.Equal(expectedHash, actualHash); var merklePath = new MerklePath { MerklePathNodes = { new MerklePathNode { IsLeftChildNode = true, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x739c9a33d81d44b3c6b511c326337c12d9f557fdc3c9476ab33f5d064785a47e")) }, new MerklePathNode { IsLeftChildNode = true, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x8487ce95823a23aac06a040828761818b2d491fb6603c5d3284b3c9c73764c87")) }, new MerklePathNode { IsLeftChildNode = true, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x7c8e76b0b80181c5154d138078d15aafd3e980858b8eb9076a3cae3fcdec76be")) } } }; var actualRoot = merklePath.ComputeRootWithLeafNode(actualHash); Assert.Equal(expectedRoot, actualRoot); } { var hex = "0x536b4d476a766941417339626e59767636634b636166626866367462524751474b393357674b765a6f436f5335616d4d4b00000000000000000000000000000000000000000000000302379bf2ca2e0000"; var expectedHash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0xdbd4b01cea12038a3b0c3ce4900c64635b96a1ee2331625fbe473d6c1e816548")); var actualHash = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(hex)); Assert.Equal(expectedHash, actualHash); var merklePath = new MerklePath { MerklePathNodes = { new MerklePathNode { IsLeftChildNode = false, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x12e2fc90c9b2c6887bf9633bf4872db4bb8cfe18619b0900dad49286abb81248")) }, new MerklePathNode { IsLeftChildNode = false, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x56ac8fe5cfe48c5ddf5d40f9a8ed5e504929935b677376cae35b8c326a97d34b")) }, new MerklePathNode { IsLeftChildNode = true, Hash = Hash.LoadFromByteArray( ByteArrayHelper.HexStringToByteArray( "0x7c8e76b0b80181c5154d138078d15aafd3e980858b8eb9076a3cae3fcdec76be")) } } }; var actualRoot = merklePath.ComputeRootWithLeafNode(actualHash); Assert.Equal(expectedRoot, actualRoot); } }