/// <summary> /// Publish a wallet contract to blockchain and save the published to local data store. /// </summary> /// <param name="newContract">A to-be-published wallet contract.</param> /// <param name="creator">Private key of the creator</param> /// <returns>Return transaction ID if published. Throw exception if there is an error.</returns> public async Task <string> PublishContract(WalletContract newContract, BitcoinSecret creator) { try { ValidateContract(newContract); } catch (Exception) { throw; } var Data = $"{DomainHex}{newContract.NameHex}{newContract.TokenHex}{BitConverterExtension.GetHexBytes(newContract.TotalSupply)}" + $"{newContract.NoOfDecimal.ToString("x4")}{newContract.Conditions.ByteArrayToString()}"; var transaction = await insightAPI.BuildTransaction(creator, creator.GetAddress(), creator.GetAddress(), Data.ToLower()); var txId = await insightAPI.BroadcastTransaction(transaction); newContract.ID = txId.txid; var status = await insightAPI.GetSync(); newContract.StartingBlock = status.blockChainHeight; newContract.LastSyncedBlock = status.blockChainHeight; UpdateContract(newContract, true); return(newContract.ID); }
public string GetOP_RETURN() { // 16 + 2 + 20 + 16 + var a = _contract.NameHex; var b = BitConverter.ToString(BitConverter.GetBytes((ushort)Operation).Reverse().ToArray()).Replace("-", ""); var c = TokenReceiverHashHex; var roundedAmount = Math.Round(Amount, _contract.NoOfDecimal); var d = BitConverterExtension.GetHexBytes(roundedAmount); string validatedReferenceCode = ReferenceCode; string e = ""; if (!string.IsNullOrEmpty(ReferenceCode)) { if (ReferenceCode.Length > 20) { validatedReferenceCode = ReferenceCode.Substring(0, Math.Min(ReferenceCode.Length, 20)); } e = BitConverter.ToString(Encoding.Default.GetBytes(validatedReferenceCode)).Replace("-", "").ToLower(); } var output = $"{a}{b}{c}{d}{e}"; return(output.Substring(0, Math.Min(output.Length, 160))); }
private void Parse() { while (true) { var type = Reader.ReadByte(); var last = (type & 0x80) == 0x80; if (last) { break; } var length = BitConverterExtension.ToInt24(Reader.ReadBytes(3), 0); switch ((MetadataBlockType)type) { case MetadataBlockType.STREAMINFO: { StreamInfo = StreamInfo.FromByteArray(Reader.ReadBytes(length)); break; } case MetadataBlockType.SEEKTABLE: { Reader.ReadBytes(length); break; } case MetadataBlockType.PICTURE: { var picture = Picture.FromByteArray(Reader.ReadBytes(length)); Pictures[picture.PictureType] = picture; break; } case MetadataBlockType.VORBIS_COMMENT: { VorbisComment = VorbisComment.FromByteArray(Reader.ReadBytes(length)); break; } default: { // Discard Reader.ReadBytes(length); break; } } } if (VorbisComment == null) { VorbisComment = new VorbisComment(); } Frame = Reader.ReadBytes((int)(InMemoryByteArray.Length - InMemoryByteArray.Position)); }
/// <summary> /// Retrieve the wallet contract according to transaction ID from the local data store. If not found, retrieve through the blockchain API. /// </summary> /// <param name="txid">Bitcoin-compatible transaction ID</param> /// <returns>Return a wallet contract if found. Return null object if not found.</returns> public async Task <WalletContract> FindContract(string txid) { WalletContract existing = null; existing = collection.Find(c => c.ID == txid).FirstOrDefault(); if (existing != null) { return(existing); } else { try { var transaction = await insightAPI.GetTransactionInfo(txid); var detectedWallet = new WalletContract(); detectedWallet.ID = txid; detectedWallet.OwnerPublicAddress = transaction.GetOwnerAddress(); var op_return = transaction.GetOP_RETURN(); if (!op_return.StartsWith(DomainHex)) { return(null); } var startBit = 32; detectedWallet.NameHex = op_return.Substring(startBit, 16); startBit += 16; detectedWallet.TokenHex = op_return.Substring(startBit, 16); startBit += 16; detectedWallet.TotalSupply = BitConverterExtension.ToDecimal(op_return.Substring(startBit, 32)); startBit += 32; detectedWallet.NoOfDecimal = ushort.Parse(op_return.Substring(startBit, 4), System.Globalization.NumberStyles.HexNumber); startBit += 4; detectedWallet.Conditions = op_return.Substring(startBit, 16).StringToByteArray(); startBit += 16; detectedWallet.StartingBlock = transaction.blockheight; detectedWallet.LastSyncedBlock = transaction.blockheight; byte[] myByte = Encoding.ASCII.GetBytes(detectedWallet.ID); var encrypted = NBitcoin.Crypto.Hashes.RIPEMD160(myByte, myByte.Length); var hashID = encrypted.ByteArrayToString(); db.DropCollection($"Ledger-{hashID}"); db.DropCollection($"Account-{hashID}"); UpdateContract(detectedWallet, true); return(detectedWallet); } catch (Exception) { return(null); } } }
public async Task SaveAsync(Stream destination) { var writeTo = new MemoryStream(); using (var writer = new BinaryWriter(writeTo)) { writer.Write(Encoding.ASCII.GetBytes("fLaC")); writer.Write((byte)MetadataBlockType.STREAMINFO); var stream = StreamInfo.ToByteArray(); writer.Write(BitConverter.GetBytes(BitConverterExtension.ConvertEndian24(stream.Length)), 0, 3); writer.Write(stream); foreach (var picture in Pictures) { stream = picture.Value.ToByteArray(); writer.Write((byte)MetadataBlockType.PICTURE); writer.Write(BitConverter.GetBytes(BitConverterExtension.ConvertEndian24(stream.Length)), 0, 3); writer.Write(stream); } stream = VorbisComment.ToByteArray(); writer.Write((byte)MetadataBlockType.VORBIS_COMMENT); writer.Write(BitConverter.GetBytes(BitConverterExtension.ConvertEndian24(stream.Length)), 0, 3); writer.Write(stream); writer.Write((byte)0x81); writer.Write(Frame); await writeTo.FlushAsync(); writeTo.Position = 0; await writeTo.CopyToAsync(destination); } }
/// <summary> /// Analyse the 8 bytes of the stream content starting from the <paramref name="offset" /> to determine if it has a valid /// TIFF header. The method return a boolean to denote if conversion was successful /// </summary> /// <param name="stream">stream content to analyse TIFF header </param> /// <param name="offset">offset position from the start of stream to analyse 8 bytes</param> /// <param name="header"> /// When this method returns, output parameter contains the TIFF header based on the supplied stream, /// if the conversion succeeded, or null if the conversion failed. /// </param> /// <returns>true if stream was converted successfully; otherwise false</returns> public static bool TryParse(Stream stream, int offset, out TiffHeader header) { header = null; try { ByteOrder byteOrder; var headerBytes = new byte[TiffHeaderByteLength]; stream.Seek(offset, SeekOrigin.Begin); stream.Read(headerBytes, 0, TiffHeaderByteLength); var endianess = Utility.Combine(headerBytes[0], headerBytes[1]); if (typeof(ByteOrder).IsEnumDefined(endianess)) { byteOrder = (ByteOrder)Utility.Combine(headerBytes[0], headerBytes[1]); } else { return(false); } if (BitConverterExtension.ToUInt16(headerBytes, 2, byteOrder, BitConverterExtension.SystemByteOrder) != TiffVersionNumber) { return(false); } var offsetOfIfd0 = BitConverterExtension.ToUInt32(headerBytes, 4, byteOrder, BitConverterExtension.SystemByteOrder); header = new TiffHeader(byteOrder, offsetOfIfd0); return(true); } catch (Exception e) { return(false); } }