/// <summary> /// Tested, 反序列化MerkleValue /// </summary> /// <param name="Source"></param> /// <returns></returns> private static ToMerkleValue deserializMerkleValue(byte[] Source) { int offset = 0; try { ToMerkleValue result = new ToMerkleValue(); //get txHash ByteString rawTxHash; (rawTxHash, offset) = readVarBytes(Source, offset); result.txHash = (byte[])rawTxHash; //get fromChainID, Uint64 result.fromChainID = Source.Range(offset, 8); offset = offset + 8; //get CrossChainTxParameter result.TxParam = deserializCrossChainTxParameter(Source, offset); return(result); } catch { throw new Exception(); } }
private static bool ExecuteCrossChainTx(ToMerkleValue value) { if (value.TxParam.toContract.Length == 20) { UInt160 TargetContract = (UInt160)value.TxParam.toContract; string TargetMethod = (string)(ByteString)value.TxParam.method; object[] parameter = new object[] { value.TxParam.args, value.TxParam.fromContract, value.fromChainID }; bool DynamicCallResult = false; try { DynamicCallResult = (bool)Contract.Call(TargetContract, TargetMethod, CallFlags.All, parameter); } catch { notify("Dynamic Call Fail"); } if (DynamicCallResult) { Storage.Put(Storage.CurrentContext, transactionPrefix.Concat(value.fromChainID).Concat(value.txHash), 1); return(true); } else { return(false); } } else { notify("Contract length is not correct"); return(false); } }
public static bool tryDeserializeMerkleValue(byte[] Source) { try { ToMerkleValue result = deserializMerkleValue(Source); return(true); } catch { return(false); } }
public static bool verifyAndExecuteTx(byte[] proof, byte[] RawHeader, byte[] headerProof, byte[] currentRawHeader, byte[] signList) { Header txheader; try { txheader = deserializHeader(RawHeader); } catch { notify("Header deserialize failed"); throw new Exception(); } ECPoint[] keepers = (ECPoint[])StdLib.Deserialize(Storage.Get(Storage.CurrentContext, mCKeeperPubKeysPrefix)); int n = keepers.Length; int m = n - (n - 1) / 3; BigInteger currentEpochHeight = (BigInteger)Storage.Get(Storage.CurrentContext, currentEpochHeightPrefix); byte[] StateRootValue = new byte[] { 0x00 }; if (txheader.height >= currentEpochHeight) { notify("New Tx executing"); if (!verifySigWithOrder(RawHeader, signList, keepers)) { notify("Verify RawHeader signature failed!"); return(false); } } else { notify("Old Tx"); Header currentHeader; if (!verifySigWithOrder(currentRawHeader, signList, keepers)) { notify("Verify currentRawHeader signature failed!"); return(false); } try { currentHeader = deserializHeader(currentRawHeader); } catch { notify("CR Header deserialize Failed"); throw new Exception(); } StateRootValue = merkleProve(headerProof, currentHeader.blockRoot); ByteString RawHeaderHash = (ByteString)Hash256(RawHeader); if (!StateRootValue.Equals(RawHeaderHash)) { notify("Verify block proof signature failed!"); return(false); } } // Through rawHeader.CrossStateRoot, the toMerkleValue or cross chain msg can be verified and parsed from proof StateRootValue = merkleProve(proof, txheader.crossStatesRoot); ToMerkleValue merkleValue = deserializMerkleValue(StateRootValue); //check by txid if ((BigInteger)Storage.Get(Storage.CurrentContext, transactionPrefix.Concat(merkleValue.fromChainID).Concat(merkleValue.txHash)) == 1) { notify("Transaction has been executed"); return(false); } //check to chainID if ((ByteString)merkleValue.TxParam.toChainID != (ByteString)chainID) { notify((ByteString)merkleValue.TxParam.toChainID); notify((ByteString)chainID); notify("Not Neo crosschain tx"); return(false); } //run croos chain tx if (ExecuteCrossChainTx(merkleValue)) { notify("Tx execute success"); } else { notify("Tx execute fail"); return(false); } //event CrossChainUnlockEvent(merkleValue.fromChainID, merkleValue.TxParam.toContract, merkleValue.txHash); return(true); }