/// <summary> /// Sign the raw transaction. /// </summary> /// <param name="rawTransaction"> /// <seealso cref="RawTransaction"/> </param> /// <returns> <seealso cref="RawTransaction"/> with signature. </returns> public static RawTransaction Sign(RawTransaction rawTransaction, ECKeyPair keyPair) { if (rawTransaction == null) { throw ClientArgumentException.Exception("raw transaction object is invalid"); } var signature = ECDSASign.SignMessage(rawTransaction.Encode(), keyPair, true); var signBytes = signature.ToByteArray(); rawTransaction.Signature = signBytes; return(rawTransaction); }
/// <summary> /// Transfer the transaction to the blockchain to be included in the next block. /// </summary> /// <param name="rawTransaction">The transaction to be included in the blockchain</param> /// <param name="client">The client that determines the interaction with the blockchain</param> /// <returns>The result of the transfer</returns> public static async Task <TransferResult> Transfer(this RawTransaction rawTransaction, VeChainClient client) { if (rawTransaction?.signature == null) { throw new ArgumentException("Unsigned transaction can not be sent"); } var bytes = rawTransaction.Encode(); var transactionString = bytes.ByteArrayToString(StringType.Hex | StringType.ZeroLowerX); return(await client.SendTransaction(bytes)); }
/// <summary> /// Transfer amount, raw transaction will be encoded by rlp encoder and convert /// to hex string with prefix "0x". Then the hex string will be packaged into /// <seealso cref="TransferRequest"/> bean object and serialized to JSON string. /// </summary> /// <param name="transaction"> /// <seealso cref="RawTransaction"/> raw transaction to to send </param> /// <returns> <seealso cref="TransferResult"/> </returns> /// <exception cref="ClientIOException"> /// network error, 5xx http status means request error, 4xx http /// status means no enough gas or balance. </exception> public static TransferResult Transfer(RawTransaction transaction) { if (transaction?.Signature == null) { throw ClientArgumentException.Exception("Raw transaction is invalid"); } var rawBytes = transaction.Encode(); if (rawBytes == null) { throw ClientArgumentException.Exception("Raw transaction is encode error"); } string hexRaw = ByteUtils.ToHexString(rawBytes, Prefix.ZeroLowerX); var request = new TransferRequest { Raw = hexRaw }; return(SendPostRequest <TransferResult>(Path.PostTransaction, null, null, request)); }
/// <summary> /// Calculates the transaction id of a signed transaction. Will throw an exception when the transaction /// is not signed. The id is not needed to submit a transaction but can be useful when transactions /// depend on each other. /// </summary> /// <param name="rawTransaction">The RawTransaction for which the id needs to be calculated.</param> /// <param name="signer">The address of the signer.</param> /// <returns>The RawTransaction with the calculated id.</returns> public static RawTransaction CalculateTxId(this RawTransaction rawTransaction, Address signer) { if (rawTransaction.signature == null) { throw new ArgumentException("transaction is not singed"); } // Hash the RLP encoded transaction var signingHash = Hash.HashBlake2B(rawTransaction.Encode()); var signingAddress = signer.HexString.HexStringToByteArray(); byte[] concatenatedBytes = new byte[52]; Unsafe.CopyBlock(ref concatenatedBytes[0], ref signingHash[0], (uint)signingHash.Length); //Array.Copy(signingHash, 0, concatenatedBytes, 0, signingHash.Length); Unsafe.CopyBlock(ref concatenatedBytes[signingHash.Length], ref signingAddress[0], (uint)signingAddress.Length); //Array.Copy(signingAddress, 0, concatenatedBytes, signingHash.Length, signingAddress.Length); // Hash the bytes from the signed transaction and the signer address byte[] txIdBytes = Hash.HashBlake2B(concatenatedBytes); rawTransaction.id = txIdBytes.ByteArrayToString(StringType.Hex | StringType.ZeroLowerX); return(rawTransaction); }