public async Task TestAddressHasInvalidTransactionsShouldBeSkippedAndReturnValidData() { var contactAddress = new Address(Seed.Random().Value); var ntruKey = InMemoryContactRepository.NtruKeyPair.PublicKey; var publicKeyTrytes = ntruKey.ToBytes().EncodeBytesAsString(); var requestAdressTrytes = new TryteString(publicKeyTrytes + Constants.LineBreak + contactAddress.Value + Constants.End).Concat(new Fragment()) .Concat(new Fragment()); var invalidBundle = CreateBundle(new TryteString("999999999999999")); var validBundle = CreateBundle(requestAdressTrytes); var messenger = new Mock <IMessenger>(); messenger.Setup(r => r.GetMessagesByAddressAsync(It.IsAny <Address>())).ReturnsAsync( new List <Message> { new Message(invalidBundle.Transactions[0].ToTrytes()), new Message(validBundle.Transactions.Aggregate(new TryteString(), (current, tryteString) => current.Concat(tryteString.Fragment))) }); var repository = new ContactRepositoryStub(messenger.Object, new SignatureValidatorStub()); var contact = await repository.LoadContactInformationByAddressAsync(new Address()); Assert.AreEqual(contactAddress.Value, contact.ContactAddress.Value); Assert.AreEqual(ntruKey.ToString(), contact.PublicKey.ToString()); }
public async Task TestAddressHasInvalidTransactionsShouldBeSkippedAndReturnValidData() { var contactAddress = new Address(Seed.Random().Value); var ntruKey = InMemoryContactRepository.NtruKeyPair.PublicKey; var publicKeyTrytes = ntruKey.ToBytes().EncodeBytesAsString(); var requestAdressTrytes = new TryteString(publicKeyTrytes + Constants.LineBreak + contactAddress.Value + Constants.End); var invalidBundle = CreateBundle(new TryteString("999999999999999")); var validBundle = CreateBundle(requestAdressTrytes); var iotaRepository = new Mock <IIotaRepository>(); iotaRepository.Setup(r => r.FindTransactionsByAddressesAsync(It.IsAny <IEnumerable <Address> >())).ReturnsAsync( new TransactionHashList { Hashes = new List <Hash> { invalidBundle.Hash, validBundle.Hash } }); iotaRepository.SetupSequence(r => r.GetBundleAsync(It.IsAny <Hash>())).ReturnsAsync(invalidBundle).ReturnsAsync(validBundle); var repository = new ContactRepositoryStub(iotaRepository.Object); var contact = await repository.LoadContactInformationByAddressAsync(new Address()); Assert.AreEqual(contactAddress.Value, contact.ContactAddress.Value); Assert.AreEqual(ntruKey.ToString(), contact.NtruKey.ToString()); }
public MaskedAuthenticatedMessage CreateMessage(TryteString message) { var tree = this.TreeFactory.Create(this.Seed, this.Start, this.Count, this.SecurityLevel); var nextRootTree = this.TreeFactory.Create(this.Seed, this.Start + this.Count, this.NextCount, this.SecurityLevel); var maskedAutheticatedMessage = this.MamFactory.Create( tree, this.Index, message, nextRootTree.Root.Hash, this.Key, this.Mode, this.SecurityLevel); if (this.Index == this.Count - 1) { this.Start = this.NextCount + this.Start; this.Index = 0; } else { this.Index++; } this.NextRoot = maskedAutheticatedMessage.NextRoot; return(maskedAutheticatedMessage); }
/// <inheritdoc /> public async Task <SendMessageResponse> ExecuteAsync(SendMessageRequest request) { if (request.Message.Length > Constants.MessageCharacterLimit) { return(new SendMessageResponse { Code = ResponseCode.MessageTooLong }); } var messageTimestamp = TryteString.FromUtf8String(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); var senderId = request.UserPublicKeyAddress.GetChunk(0, 30); var encryptedMessage = await Task.Run( () => new NtruKeyExchange(NTRUParamSets.NTRUParamNames.E1499EP1).Encrypt( request.KeyPair.PublicKey, Encoding.UTF8.GetBytes(request.Message))); var encryptedPayload = new TryteString(encryptedMessage.EncodeBytesAsString()); var payloadSignature = Constants.FirstBreak.Concat(senderId).Concat(Constants.SecondBreak).Concat(messageTimestamp); var firstMessagePartPayload = encryptedPayload.GetChunk(0, 2070).Concat(payloadSignature).Concat(new TryteString("A")).Concat(Constants.End); var secondMessagePartPayload = new TryteString(encryptedPayload.Value.Substring(2070)).Concat(payloadSignature).Concat(new TryteString("B")) .Concat(Constants.End); await this.Messenger.SendMessageAsync(new Message(MessageType.ChatMessage, firstMessagePartPayload, request.ChatAddress)); await this.Messenger.SendMessageAsync(new Message(MessageType.ChatMessage, secondMessagePartPayload, request.ChatAddress)); return(new SendMessageResponse { Code = ResponseCode.Success }); }
public static async Task <List <Contact> > GetPublicKeysAndContactAddresses(TangleMessenger tangleMessenger, string receiverAddress, bool dontLoadSql = false) { var trytes = await tangleMessenger.GetMessagesAsync(receiverAddress, 3, false, dontLoadSql); var contacts = new List <Contact>(); foreach (var tryte in trytes) { var trytesString = tryte.Message.ToString(); if (!trytesString.Contains(ChiotaConstants.LineBreak)) { continue; } try { var index = trytesString.IndexOf(ChiotaConstants.LineBreak, StringComparison.Ordinal); var publicKeyString = trytesString.Substring(0, index); var bytesKey = new TryteString(publicKeyString).DecodeBytesFromTryteString(); contacts.Add( new Contact { NtruKey = new NTRUPublicKey(bytesKey), ContactAddress = trytesString.Substring(index + ChiotaConstants.LineBreak.Length, 81) }); } catch { // ignored } } return(RemoveDuplicateContacts(contacts)); }
public void TestToBytesDoesGenerateCorrectLength() { var tryteString = new TryteString("FFWEHDTAQFFDNEUGLAIDHHSAEHTGEDQEVBGHVHGFLCWDM9L99GOFWAA99EDBQCJCACZEZAC9UEYGZ9Q9DFNBEDRB9GGAZAV9VH9FTAODRAMGMDSHUGX9LH9HVBOFRBLENFN9YEEFVGI9QDJBF9KHCH9IEFYAZHMBPDEFNDHBPBLACHEIAECBZFHHLAQBCILGEDQDAB9HVDOFNBXFMBNHVFOBZA9CIGCCGHO9DCUDFEFCPFIHJDK9VDTGRGGEF9CBVDQAAECERF9D9CYHCHPBDFTDXEFEN9EEOBFHXDBBPANCPBVDTGGFUGGHXGACKBF9M9FHMFKDR9GCRBEAFFWEKB9IMBTALFKDXBBAPEXETCZCM9B9QECBGDKCQDNEDF9BDFLCX9YHMG9HC9MDSCCBSCKATCD9VAFHPHZDG9DCTD9FYGP9WE9GHIL9BHNGSEC9E9WCKHIDYFY9EBWEQBYHXCO9HFQHWFTDODIDKHDCMFMCLBVCVAH99FECEIEGOFKCC9N9Y9GEN9LGZCIGDDAARHEI9BGGSBGFJEBFJFLHOH9HF9U9QAGCLBQAECBIBATEJIWDNDKGVCLIVGABKFEBXCADQHY9L9MFCFT9LETCXASFEF9GWCMH9DTAQDIACEZBR9XABAZEZBZCKCG9FBIDVELEDETANHFCLCVFEGFDT9GD9E9FJ9Y9FFJAWGAID9UDLDQAEFIAMAXCW99IWAVBM9DAZEQ9ZHKBYEOESBABJEYE9AGFZDEGG9MGXAEBVEYESCIGBFGAGHKIGIY9RBVBDFTELFICQEMASEUBAHNCUCJEC9BAGBECVFTCVELBC9SHICKAF9KAMDVBT9V9X9YBCHHCQFOBCFLDICLAXEKER9IFACCAIIRGB9VFMDWCTGRFQHXDQHL9T9FGIIICA9E9UFRAWALGZEBHOBPCNCK9LEKIBHZAJHUBGICBLBCDUHNAQHJBJ9KGS9TEGEXHBGEHBBSEJBRBJANDB9GGRDCGZBRFTETEK9IEK9TDZBABUFE9IGABEDTFGFDGBFXHECY9Z9ZBCD9DOCJCCBWHQGJHCALATHB9VDYC9CDHAGB9GC9B9HEEBCHCIEUGHFJHCGLEUFDDAGKFG9SCXBLHUCV9ADPESBXBLFRFLGKHZGZBZEXFMES9CBHAEHQGWCVBZFKFM9IHYHRA9GPAL9NAV9AEJHGILAQDKDICJHRAABUDN9YGKHBIGAG9ICIIYEZ9WGCANHCGBEBCBGQBJCN9EGFCLAIBCDHHHHRFR9D9DGEALCPAECDEY9LFIFFIEEJDHEDDF9JGVHAISDW9NBFAQ9IA9FNAZH9EY9AEDCY9NHS9TEJ9AEQFCEGFHGHFYGNFQAVHAHT9EFXHWAIBVCFGJFLHAD9AKAXE9HAHVCWAIFIBAFVBC9PBDBVFDAT9LFKFCACEKFACUEHDHEHDOBSFSHJEACODUFKDPCVCMHEAHHJBDBGGPBHFIASBJDJIGGGFGFIEJ9XBABQEEBLFSAGAYFK9AIYFCFBIEESDZCXDFFUDVGHAFEFDJGAISELIVFAADDPCFCICLBKHDHIEIEGHG9KCTETDFCGEN9VCV9ACYELAVERHPFLIT9KDYFQHOBH9PFEAIIFIMBDALECECDTBCGOCLGUCK9SBFALHRETFV9GGQHTGKAGELHOEYGYHECCFZCNCIHDIF9TGOBVCVDWCXHQFYDDEAISGGATEPEHGW9LFAITEYCYDMG9DRGFAYCJ9OCVHWHLAGBRHKIFIY9JFTFSCV9PAVHTFA9A999EGIAAIEHPEECCBWDM9OCAADFIAWFAGSDJGOAVCCD9ACADHIIMGJGP9OCNGIDNDSCHCX9IEMCLATGBEKGZFXGDFYABGE9LEN9RAJIMASBI9YATHREFDNEYDFCLEDFGCKAIFDCODFEOBCDPDIGO9Y9DHUAADAFBAZE99UHBEUGQAVDK99COGT9XATGLIMFSEYDD9XCYBJ9FGXANAWDJ9C9GFCAXAGEBDGFLEODVAM9MFSHTBTGJHEDC9GCIBLCSBKCNGHA99"); var bytes = tryteString.ToBytes(); Assert.AreEqual(1022, bytes.Length); }
public void TestUtf8StringConversion() { var stringValue = "┬"; var tryteString = TryteString.FromUtf8String(stringValue); Assert.AreEqual(stringValue, tryteString.ToUtf8String()); }
public static byte[] DecodeBytesFromTryteString(this TryteString tryteString) { var trytesArray = new List <string> { "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; // If input length is odd, return null if (tryteString.Value.Length % 2 != 0) { return(null); } var byteList = new List <byte>(); for (var i = 0; i < tryteString.Value.Length; i += 2) { var firstValue = trytesArray.IndexOf(tryteString.Value.Substring(i, 1)); var secondValue = trytesArray.IndexOf(tryteString.Value.Substring(i + 1, 1)); var value = firstValue + (secondValue * 27); byteList.Add(Convert.ToByte(value)); } return(byteList.ToArray()); }
public async Task TestIndexHasBeenWrittenFromAnotherSourceShouldSkipIndex() { var seed = Seed.Random(); // Publish a message as if it was published from another app var tempProvider = new InMemoryDeterministicSeedManager( new InMemoryResourceTracker(), new IssSigningHelper(new Curl(), new Curl(), new Curl()), new AddressGenerator(), IotaResourceProvider.Repository); var credentials = await tempProvider.CreateChannelCredentialsAsync(seed); var channel = new MamChannelFactory(CurlMamFactory.Default, CurlMerkleTreeFactory.Default, IotaResourceProvider.Repository).Create( Mode.Restricted, credentials.Seed, IotaFhirRepository.SecurityLevel, credentials.ChannelKey); var message = channel.CreateMessage(TryteString.FromAsciiString("Test")); await channel.PublishAsync(message, 14, 1); // Create credentials that should skip the first index var provider = new InMemoryDeterministicSeedManager( new InMemoryResourceTracker(), new IssSigningHelper(new Curl(), new Curl(), new Curl()), new AddressGenerator(), IotaResourceProvider.Repository); await provider.CreateChannelCredentialsAsync(seed); Assert.AreEqual(1, provider.CurrentIndex); }
private async Task <GetContactsResponse> CrossCheckAsync( IAsymmetricKeyPair keyPair, TryteString publicKeyAddress, List <Contact> approvedContacts, IEnumerable <Contact> pendingContactRequests) { var pending = new List <Contact>(); foreach (var contactRequest in pendingContactRequests) { var requestedContactsMessages = await this.Messenger.GetMessagesByAddressAsync(new Address(contactRequest.ContactAddress)); if (this.TryParseNonces(keyPair, requestedContactsMessages)) { await this.ContactRepository.AddContactAsync(contactRequest.ChatAddress, true, publicKeyAddress.Value); approvedContacts.Add(contactRequest); } else { pending.Add(contactRequest); } } return(new GetContactsResponse { ApprovedContacts = approvedContacts, PendingContactRequests = pending, Code = ResponseCode.Success }); }
public void TestTransferMessageDoesNotFitIntoOneTransactionShouldCreateSecondTransaction() { var transfer = new Transfer { Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB") { Balance = 42 }, Message = TryteString.FromString(GetSuperLongMessage()), Tag = Tag.Empty }; var bundle = new Bundle(); bundle.AddTransaction(transfer.Address, transfer.Message, transfer.Tag, 999999999L); Assert.AreEqual(2, bundle.Transactions.Count); var transactionOne = bundle.Transactions[0]; Assert.AreEqual(transfer.Address, transactionOne.Address); Assert.AreEqual(transfer.Tag, transactionOne.Tag); Assert.AreEqual(transfer.Address.Balance, transactionOne.Value); var transactionTwo = bundle.Transactions[1]; Assert.AreEqual(transfer.Address, transactionTwo.Address); Assert.AreEqual(transfer.Tag, transactionTwo.Tag); Assert.AreEqual(0, transactionTwo.Value); }
/// <inheritdoc /> public MaskedAuthenticatedMessage Create( MerkleTree tree, int index, TryteString message, Hash nextRoot, TryteString channelKey, Mode mode, int securityLevel) { var nextRootTrits = nextRoot.ToTrits(); var messageTrits = message.ToTrits(); var indexTrits = Pascal.Encode(index); var messageLengthTrits = Pascal.Encode(messageTrits.Length); var subtree = tree.GetSubtreeByIndex(index); this.Curl.Reset(); this.Curl.Absorb(channelKey.ToTrits()); this.Curl.Absorb(tree.Root.Hash.ToTrits()); var payload = new List <int>(); payload.InsertRange(0, indexTrits); payload.InsertRange(indexTrits.Length, messageLengthTrits); var nextRootStart = indexTrits.Length + messageLengthTrits.Length; this.Curl.Absorb(payload.Take(nextRootStart).ToArray()); // encrypt next root together with message trits payload.InsertRange(nextRootStart, this.Mask.Mask(nextRootTrits.Concat(messageTrits).ToArray(), this.Curl)); // calculate message end and add nonce var messageEnd = nextRootStart + nextRootTrits.Length + messageTrits.Length; this.AddNonce(securityLevel, messageEnd, payload); // create signature, encrypt signature + sibling count (get trits from pascal) + siblings var signature = this.SigningHelper.Signature(this.Curl.Rate(Constants.TritHashLength), subtree.Key.ToTrits()); var subtreeTrits = subtree.ToTryteString().ToTrits(); var siblingsCount = subtreeTrits.Length / Constants.TritHashLength; var encryptedSignature = this.Mask.Mask(signature.Concat(Pascal.Encode(siblingsCount)).Concat(subtreeTrits).ToArray(), this.Curl); // insert signature and pad to correct length (% 3 == 0) payload.InsertRange(messageEnd + NonceLength, encryptedSignature); PadPayload(payload); this.Curl.Reset(); var messageAddress = this.GetMessageAddress(tree.Root.Hash, mode); return(new MaskedAuthenticatedMessage { Payload = CreateBundleFromPayload(messageAddress, payload), Root = tree.Root.Hash, Address = messageAddress, NextRoot = nextRoot }); }
/// <summary> /// The execute. /// </summary> /// <returns> /// The <see cref="Task"/>. /// </returns> public async Task Execute() { var seed = Seed.Random(); var channelKey = Seed.Random(); // To send a message we first create a channel via factory. Note that only one seed should be used per channel // If your channel key is not an ASCII string, create the channel like this this.ChannelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey.Value, true); var channel = this.ChannelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey.Value); // Creating a message is rather easy. The channel keeps track of everything internal var message = channel.CreateMessage(TryteString.FromAsciiString("This is my first message with MAM from CSharp!")); // Nevertheless we still need to publish the message after creating it await channel.PublishAsync(message); // Creating a message is rather easy. The channel keeps track of everything internal var message2 = channel.CreateMessage(TryteString.FromAsciiString("This is my second message with MAM from CSharp!")); // Nevertheless we still need to publish the message after creating it await channel.PublishAsync(message2); Console.WriteLine($"Seed: {seed.Value}"); Console.WriteLine($"ChannelKey: {channelKey.Value}"); Console.WriteLine($"Root: {message.Root.Value}"); }
public static Contact FilterRequestInfos(IEnumerable <TryteString> trytes) { var contact = new Contact(); var oneKeyAlreadyFound = false; foreach (var tryte in trytes) { var trytesString = tryte.ToString(); if (!trytesString.Contains("9CHIOTAYOURIOTACHATAPP9")) { continue; } if (oneKeyAlreadyFound) { return(null); } var index = trytesString.IndexOf("9CHIOTAYOURIOTACHATAPP9", StringComparison.Ordinal); var publicKeyString = trytesString.Substring(0, index); var bytesKey = new TryteString(publicKeyString).ToBytes(); contact.PublicNtruKey = new NTRUPublicKey(bytesKey); contact.ContactAdress = trytesString.Substring(index + 23, 81); oneKeyAlreadyFound = true; } return(contact); }
public static List <ChatMessage> FilterChatMessages(IEnumerable <TryteString> trytes, NtruKex ntruKex, IAsymmetricKeyPair keyPair) { var chatMessages = new List <ChatMessage>(); foreach (var tryte in trytes) { try { var trytesString = tryte.ToString(); var indexBreak = trytesString.IndexOf("9CHIOTAYOURIOTACHATAPP9", StringComparison.Ordinal); var messageTrytes = new TryteString(trytesString.Substring(0, indexBreak)); var dateTrytes = new TryteString(trytesString.Substring(indexBreak + 23, trytesString.Length - indexBreak - 23)); // can only decrypt messages from other user (send with own public key)! var decryptedMessage = ntruKex.Decrypt(keyPair, messageTrytes.ToBytes()); var date = DateTime.Parse(dateTrytes.ToUtf8String()); var chatMessage = new ChatMessage { Message = decryptedMessage, Date = date }; chatMessages.Add(chatMessage); } catch { continue; } } return(chatMessages); }
public async Task <bool> SendMessageAsync(TryteString message, string address, int retryNumber = 3) { var roundNumber = 0; while (roundNumber < retryNumber) { //this.UpdateNode(roundNumber); var bundle = new Bundle(); bundle.AddTransfer(CreateTransfer(message, address)); try { await this.Repository.SendTransferAsync(this.seed, bundle, SecurityLevel.Medium, Depth, this.MinWeight); return(true); } catch (Exception e) { Trace.WriteLine(e); roundNumber++; } } return(false); }
public void TestAggregateTransactions() { var fragmentOne = TryteString.FromUtf8String("TestFragmentOne"); var fragmentTwo = TryteString.FromUtf8String("TestFragmentTwo"); var bundle = new Bundle(); bundle.AddTransfer(new Transfer { Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"), Message = fragmentOne, Tag = Tag.Empty }); bundle.AddTransfer(new Transfer { Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"), Message = fragmentTwo, Tag = Tag.Empty }); var expectedPayload = bundle.Transactions[0].Fragment.Concat(bundle.Transactions[1].Fragment); Assert.AreEqual(expectedPayload.Value, bundle.AggregateFragments().Value); }
public override async Task <PublishVerifiableClaimsReply> PublishVerifiableClaims(PublishVerifiableClaimsRequest request, ServerCallContext context) { m_logger.LogInformation("PublishVerifiableClaims start"); try { var channel = m_mamChannelFactory.Create(Mode.Restricted, new Seed(request.Seed), securityLevel: SecurityLevel.Medium, channelKey: request.SideKey, keyIsTrytes: true); var attestationJson = CreateAttestationFromRequest(request); m_logger.LogInformation($"Remove before production! PublishVerifiableClaims Attestation JSON={attestationJson}"); var message = channel.CreateMessage(TryteString.FromUtf8String(attestationJson)); await channel.PublishAsync(message, minWeightMagnitude : 10); m_logger.LogInformation($"Remove before production! PublishVerifiableClaims Message={JsonSerializer.Serialize(message)}"); return(CreatePublishVerifiableClaimsReplyFromMessage(message)); } catch (Exception ex) { m_logger.LogError("CreateVerifiableClaims", ex); throw new RpcException(new Status(StatusCode.NotFound, ex.Message)); } finally { m_logger.LogInformation("PublishVerifiableClaims end"); } }
/// <summary> /// The init. /// </summary> /// <param name="messageRoot"> /// The message root. /// </param> /// <param name="mode"> /// The mode. /// </param> /// <param name="channelKey"> /// The channel key. /// </param> /// <param name="nextRoot"> /// The next Root. /// </param> public void Init(Hash messageRoot, Mode mode, TryteString channelKey = null, Hash nextRoot = null) { this.MessageRoot = messageRoot; this.Mode = mode; this.Key = channelKey; this.NextRoot = nextRoot; }
public void TestTransferMessageDoesNotFitIntoOneTransactionShouldCreateSecondTransaction() { var transfer = new Transfer { Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"), Message = TryteString.FromAsciiString(GetSuperLongMessage()), Tag = Tag.Empty, ValueToTransfer = 42 }; this.bundle = new Bundle(); this.bundle.AddTransfer(transfer); Assert.AreEqual(2, this.bundle.Transactions.Count); var transactionOne = this.bundle.Transactions[0]; Assert.AreEqual(transfer.Address, transactionOne.Address); Assert.AreEqual(transfer.Tag, transactionOne.Tag); Assert.AreEqual(transfer.ValueToTransfer, transactionOne.Value); var transactionTwo = this.bundle.Transactions[1]; Assert.AreEqual(transfer.Address, transactionTwo.Address); Assert.AreEqual(transfer.Tag, transactionTwo.Tag); Assert.AreEqual(0, transactionTwo.Value); }
/// <summary> /// The load contact information from tangle. /// </summary> /// <param name="transactionHashes"> /// The transaction hashes on address. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> private async Task <TryteString> LoadRawContactInformationFromTangle(IEnumerable <Hash> transactionHashes) { TryteString latestContactInformation = null; foreach (var transactionHash in transactionHashes) { var contactInformationBundle = await this.IotaRepository.GetBundleAsync(transactionHash); var bundleTrytes = contactInformationBundle.Transactions.Aggregate( new TryteString(), (current, tryteString) => current.Concat(tryteString.Fragment)); if (!bundleTrytes.Value.Contains(Constants.End) || !bundleTrytes.Value.Contains(Constants.LineBreak)) { continue; } if (latestContactInformation == null) { latestContactInformation = new TryteString(bundleTrytes.Value.Substring(0, bundleTrytes.Value.IndexOf(Constants.End, StringComparison.Ordinal))); } else { throw new MessengerException(ResponseCode.AmbiguousContactInformation); } } return(latestContactInformation); }
public void TestRestrictedMessageCreation32Bit() { var expectedPayload = new Bundle(); expectedPayload.AddTransfer(new Transfer { Address = new Address(), Message = new TryteString("AQRAQLYEXHTXQUVYAXBDJZFWM9QPHXNQRVVGEODVNZAQMPXIHVYDFLHKDBFLSEUDGHVGNYFLEBQTJORJ9BDWXYUBYQDBKYHXGCIRVRJLLRQCBFSYYFTRVRPYJTHIIOOFDISBILGHQCWXSNLRXRKPTBSBO9ENPHHCSTPGFEVK9GVOWCBTJKVRANFBPHEOQNTJJQNYWQSYYRXZMFHADWUQJVBOLP9BUV9PXUIAKDUGRICOLQXXSXNGNMUMBWJRJDBSUJWSPGLXMHBLUUSSWSQUTSWKRRPWURYJYHRHSRCLBEBMHKVFJMLYDDEIHHBCAZYLLNGMFTUSUZA9VAWSSFSKLDIFYDDZJXJZ9VRIADVEAPMRBBUAOJCWCWMBUEVGBFMXPHQEE9JNPLLSDBDJSLXZXISGDOAMGQSVMOMKOWTWJPYCDKXRRBBKLPJRJMN9LJZQZADQQYXNBNFQDBITXBXPSMWDNNJAODPSEJRQZCKTLSOLUIMOWXZHYXJOXAGRJC9NNGWLYY9VQYW9IYFCQWDZQJDNWHVIXEIYSHTSOGRHMPQZ9YUTWDCRUEZGJTKVDRFNZVRBVAJBBNHILDFSBPNJKBUVXW9CDOEGVFPAWUZROYEBYT9NHI9DNGLHWPSKMJELJSMVTRNGEJNAMNEWUQ9GSRANMRIEB9GWXJD9GX9EHTRNYEYZJFKALYJVPUITHKGMM9QJDOKHWXQ9YN9ZBBCRNESWWBPWZIQVGWDQSRVROIRTPK9STFWRDDUFDKSLQQOXRWSSQCOHIJUJLPOBUVNWLOGGXDMEFOQHXSGQOZVQGYLUABLBJHXZRRIB9ZTLAXHHSRHAODYTSDTJUGRWVDJAJNRNDL9YVEPKLVAQFPAONMKOHHCLAZWFTAZTMEQKGNMNBYHBGNNOV99HCMQDRZEGGPAWA9FFO9SESTP9TSFXLCYPJJ9JKROY99VVHENCHSSSXKDAFRGOKAKIWCOHXYNFPKKWCBSGENRBX9FQFBITIO9999USHGAMQMBYPYPQANDGZXIPYVFZCTRGALNR9XGZBYAKQYIJDSBTWHIJQMOVOVBVCRUXZD9IGMODZPXLGTKYOWRVQC9YYVVBVMDRSUUPJDJUMLNCPGZJLTGQPQOXKGKUWASQQ9AER9JLWMQA9GLPATMVRDFIWLC9GBIKRXGJSZLPZVKGTWIIDCGXIDKMLQTCWTPICN9UZZXEOFFCQSJPOXFSCEHJNGIGOYIFZFMPWHJOFZGIYRFWOZCSSHKPWHDEELMN9ZWULHRMRHVNGTNUEZEMRINSVYEGBOJMNYFWNLFSIHHRIFXZRLEGFIEOT9WYZQXFTKXRAYRRKDV9VYUBSZAKARAIZYDWBEDLLOCAXQZIXSIRFGCGZWVRRCME9TXPTDUYLYUGLIBENQ99SDQLYFBJZHGQYQBLJMLFZLQLPHYMCFMTOSDA99DXAMCEAMBGNFFDJIKTUCBHSYKH9KLRVBYXOJJYKZYXJLIKIZFQHNFWWNCQACXZIXDLJXNU9UNZQJMFLJJXGSEPXIFRDKSUENGGELMFPVQKHAYPHMIPHVKZTNFTWMERRTVFHJLKILHRX9XSVYJZQKQXIMIMPDGCNXZKXUBNZOVXMCZXGXZTVBTIQUZ9GDQJGIHFKFXYZHDNGPIUXLIKSDBQQNMJCVRJUKQVJWGOFOBTXDSFLM9BGYZJREIBUBEVCOME9NNKHFEKWGJRTMZFDHFZY9YHTFJNCNZBGMVEEKUYPZBYQQFVVZEFSQDXOWTNUSU9GUTS9ITJAYYELPZYITWELVOAKMPTUIL9UJD9TN9HVLIYWAHMQBIHLUSBRSAGXQRAOOKGIBYMM9AOLC9DQVMNFMPGDSQUTWMRKVKE9FRZNCQJDVDKBINILRFKBEEDZTWI9UUCNLIMT9MLQRMBRJQLKHJXEKWJDEK9WAKXUJVWMUNLBUSVYSUZDOIEJAKZZOWPQFNKDLPDICGTQKOSBPWKHGPBUWYXWYVPIOIELDLIBPI9FJRSHVEKRNMQ9VPOCCCASWKL99TZCFNHLHVMOOFNBGSRXYKCKJOLNEBYAFCRMDHOVWUZ9MIFDSRRFSHSIWIN9WLLXMOKCXYTTESFZUNMQAHYVOVQQH9YZVOQATUPEPGCCGTPBAAOSPJ9ALPYXONR9OCODZDJPNPMQIREEXICFQIWRZ99OPS9ALP9GLPTTWGRJHATSJJTEKFZDJYEUKBIAACLOALTSXWCCL9GBUTWIXVEW9HYLVKRRRAATNYMGSAKLUN9HJQPIMXJOYIDXNONMHXZUGXOFIQIFBTPYDXXMKOAUUNOJU9IIXFLSSWKOCRJKXNWKKAMJRMFYSMAOWSCI9NTRQKT99CIDHJMZWSDKAIKOYWHSCJZRQWWDZOC9TKXHXCDN9GTMMGXXHXIJFMTCQFTDAKPEPQLNVCIE9UMIYXHDQUGPJSHPMRFCHMPGOYHVATXBIGOCZAFDNTVMJRJIVQDLNQYNSASMLXPSFUMYBGHXTCFYDLOGOCDTWPZMVPKMP9EEXEKNMSTEQKFZIVU9DKHSEQA9XQNOKUK9ABSTZ9XRPDMDECMYRRGSYHEZDAWEDGTQSMRC9DQ9FUWS9QELTDYZCRFYABZKVLCFGVKYGYIWJGNQKI9ONMXWFJNFIEPZRSSLNUUQOXK9YXQYMWR9B9UAUXYYONKYUG9JAJOUMLKQOXBD9JBLAQHXBJINNLBXKYGYLPRLASOFISEFXG9KENN9YFFP9J9NVVYKAEFAUTIQRDTVKVHQYEWJOGQEUPSWEIMYWYYEZRGJUEDAHDYPQEGX9KTUODLORTCJZGJCKFGEJTWRGEACRRINEQBUWS9NUPP9BMONGQQABVGBLRQXZJYXDHS9DFWAWLOZVKSDZD9UGBPKDCHLYEAUOABXKMNWTSUZTHTZBYOALUHQHSEK9WPGWGVNQEGVDDFZJXLAYINRUQYQBROPB9RGAFWMPOBOANCGW9DJJ9NUIHLQE9RNZOHLPYAIACONJXYFRBAOVJEWOTO9HZCZOVJGHQOGGJAB9QUWDRI9KLX9EGOHGTJIYQHTTMAAETKGBLDQXGRTJOEHRIAPXACPFTVGIXUJFZXUCX9EHUESMGQN9EHXEQTSKJHWDIR9OJYP9USDPWECONYRTFZREIZHOBAOXK9FCEOWCLUNKEWKE9JPQGDZ9PWAVQUMNBLVMESODMGJAIVNVJSFTQFL9RTTCJAFIMIGXASIREOXLNVEHMHPQZIKIPRQWFGYLQHVPMBNIWTWINSKW9WIWVDKHAIHNMBOCETYLNTJMA9XMEVQBPUFPKXJHXHPQCFKF9UYQQFKBBPPZMNAKPMMHPLBPDAOACLZ9HKVFGGMQHHHQLWYWYYGNXPEITKTVNURENFBAOBXITZDYCUSASIYEVJBYDLBIMUF9HILXKYH9IDYOFEQMBHJJBFDTNPDXSNSXCPUFGRIOXNYOSKHBILRWEFWZELL9GLNQOMPLMAPTOIJXSQXNPIW9XLMYEYVTNM9BVLVAIPZSYTCHHXGBQXHCBOQAUHZXKDWUREOOGKK9S9ZTKHGIQWHZOOFCGXBBCSYPGOGNRJLGVNWAGJZWKKLTHCJG9FJVRXMHQARRAHGUTITDDIMTIZAYARKJMQFCEAAOTHSHXDQKSNGMN99YGWRNLNMJXXFIQD9THOIHINYIEJMWRCZTAHJC9QIAKDIHIELNIMDKHFFWVCAHGMITJYNZ9XZSLFCGFFEQLONULNTQAJLOJTWO9BJQEBGTY9OCJBXKXNDEJWCDRYCNFDKYODHPAHQBGDXHMLVETVNRLRIJDHKAHZBAOFGMQFSTHPHBXKRAJFVIUDCKGNCDD9XTFDVNW9RLRNN9QRRUGOTMRRSVISCWE9ALTXCOCYHIQGXLGDB9RGICVSTUHJFWMWQCUICLJZCACGYCUHMGTGEJGAACGEXKJNJWKUGXRNBTEKIYUNXZZHXASCBPRDJAVXWESHU9DW9UVPJLWBKUXPDAIQ9JQPAHPMGVRUY9RLAMRTOKDVVUAZAPMNBSHRNNYDGC9BKAKKBPGHFDOHXCFWNSH9FZUMQHXMIUYKQLKHAYXPNEDYDUXTZXUKTBRJGBSZFMCNRZIQQLOLPRZPZBCX9EZBRUFGHGHBLYBLYYWZACGWGYRGV9IGZLTXOIMSCOTBNIGUXMOPVOFKIEUZASTZAHKXLYECJFLVZCORRFYDNVCYSKFCREQXXMDEHPSQFDERBICWFMOJS9PPSQYTVEXYSYGHWIWITZHRBZLHJWUYWQCAPLSBYJTJGCUXQPITAUJX9WEUVJDNUNKSDLHWDWKDQARSRKSLGLUCDNCERMKOJXCRXWCCYIAQZVGJLYTYQNGUDYYMXXL9XDBLEWPRMAY9DMMUHYUPMNBRRXJDIFDWEFJBRPYMPDPIPGXGXBMZ9JHAOISUMCNGUNCCPWKFJNBR9ZATRMDTOFDKMBQEZSCDSBNNEIUUCDHPHFBOBXLNGPOVZCATQRKVYSQHSHIVFZTW9BHPTPXUJGNNUBHWLZF9TBA9JONTWZRWHGHFIQGHAKSWBAHB99"), Tag = new Tag("ASDF"), Timestamp = Timestamp.UnixSecondsTimestamp }); expectedPayload.Finalize(); expectedPayload.Sign(); var seed = new Seed("JETCPWLCYRM9XYQMMZIFZLDBZZEWRMRVGWGGNCUH9LFNEHKEMLXAVEOFFVOATCNKVKELNQFAGOVUNWEJI"); var channelFactory = new MamChannelFactory(CurlMamFactory.Default, CurlMerkleTreeFactory.Default, new InMemoryIotaRepository()); var channelKey = new TryteString("NXRZEZIKWGKIYDPVBRKWLYTWLUVSDLDCHVVSVIWDCIUZRAKPJUIABQDZBV9EGTJWUFTIGAUT9STIENCBC"); var channel = channelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey); var message = channel.CreateMessage(new TryteString("IREALLYWANTTHISTOWORKINCSHARPASWELLPLEASEMAKEITHAPPEN")); Assert.AreEqual("RRPXQHDJY9BKXC9NGHDCSHRIDYORSUUEPFHXPQVDGSQTVYPCGVIZRWQINOUYFDUXTHFTKHLBOLYLHMKE9", message.Root.Value); Assert.AreEqual("BAVSMNXFTVBBEPXVROQYWBFHAELANDS9UFLDEOERJGKMXOGTL9UBEJF9WUDNGKUEDFZYAAFACRRRACDHV", message.Address.Value); Assert.AreEqual("OLHRFQPHPPQWTVSZNIZEKFOB9JPWKWQQPUCNLFAVEYCL9QVXRWFTDT9KPIHERRULOOBUKTJZJWKENTPLO", message.NextRoot.Value); Assert.AreEqual("OLHRFQPHPPQWTVSZNIZEKFOB9JPWKWQQPUCNLFAVEYCL9QVXRWFTDT9KPIHERRULOOBUKTJZJWKENTPLO", channel.NextRoot.Value); for (var i = 0; i < expectedPayload.Transactions.Count; i++) { Assert.AreEqual(expectedPayload.Transactions[i].Fragment.Value, message.Payload.Transactions[i].Fragment.Value); } }
public void TestConversionFromTrytes() { var trytes = new TryteString("RBTC9D9DCDEAUCFDCDADEAMBHAFA"); var output = trytes.ToAsciiString(); Assert.AreEqual("Hello from C#!", output); }
private RestRequest CreateRequest(TryteString branchTransaction, TryteString trunkTransaction, IEnumerable <Transaction> transactions, int minWeightMagnitude) { var request = new RestRequest(Method.POST) { RequestFormat = DataFormat.Json }; request.AddHeader("X-IOTA-API-Version", "1"); if (!string.IsNullOrEmpty(this.ApiKey)) { request.AddHeader("Authorization", $"powsrv-token {this.ApiKey}"); } request.AddJsonBody( new Dictionary <string, object> { { "command", CommandType.AttachToTangle }, { "trunkTransaction", trunkTransaction.Value }, { "branchTransaction", branchTransaction.Value }, { "minWeightMagnitude", minWeightMagnitude }, { "trytes", transactions.Select(transaction => transaction.ToTrytes().Value).Reverse().ToList() } }); return(request); }
public static string ComputeHash(string rawData) { using (var hashAlgorithm = SHA256.Create()) { var bytes = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(rawData)); return(TryteString.FromBytes(bytes).Value); } }
/// <summary> /// The main. /// </summary> /// <param name="args"> /// The args. /// </param> private static void Main(string[] args) { var repository = new RestIotaRepository(new RestClient("https://field.deviota.com:443"), new PoWSrvService()); var bundle = new Bundle(); bundle.AddTransfer(new Transfer { Address = new Address(Hash.Empty.Value), Tag = new Tag("MYCSHARPPI"), Timestamp = Timestamp.UnixSecondsTimestamp, Message = TryteString.FromUtf8String("Hello from PiDiver #1!") }); bundle.AddTransfer(new Transfer { Address = new Address(Hash.Empty.Value), Tag = new Tag("MYCSHARPPI"), Timestamp = Timestamp.UnixSecondsTimestamp, Message = TryteString.FromUtf8String("Hello from PiDiver #2!") }); bundle.Finalize(); bundle.Sign(); repository.SendTrytes(bundle.Transactions); Console.WriteLine("Done"); Console.ReadKey(); }
public static TryteString TryteStringIncrement(this TryteString tryteString) { // e.g. for "AAAAA" 10.596.375 possibilities var counter = 0; foreach (var character in tryteString.Value) { if (character == '9' || character == 'Z') { counter++; } else { // increments one letter // ZAC - ZBC var strBuilder = new StringBuilder(tryteString.Value) { [counter] = (char)(Convert.ToUInt16(character) + 1) }; if (counter != 0) { // ABC strBuilder[counter - 1] = 'A'; } return(new TryteString(strBuilder.ToString())); } } return(tryteString); }
public void TestChunksAreSlicedCorrectly() { var tryteString = new TryteString("IAMGROOTU"); var chunks = tryteString.GetChunks(2); Assert.AreEqual(5, chunks.Count); }
public MamChannel Create( Mode mode, Seed seed, int securityLevel = SecurityLevel.Medium, string channelKey = null, bool keyIsTrytes = false, Hash nextRoot = null, int index = 0, int count = 1, int nextCount = 1, int start = 0) { var channel = new MamChannel(this.MamFactory, this.TreeFactory, this.Repository); channel.Init( mode, seed, securityLevel, channelKey != null ? keyIsTrytes ? new TryteString(channelKey) : TryteString.FromAsciiString(channelKey) : Hash.Empty, nextRoot, index, count, nextCount, start); return(channel); }
/// <summary> /// The main. /// </summary> /// <param name="args"> /// The args. /// </param> private static void Main(string[] args) { var repository = new RestIotaRepository( new FallbackIotaClient( new List <string> { "https://invalid.node.com:443", "https://peanut.iotasalad.org:14265", "http://node04.iotatoken.nl:14265", "http://node05.iotatoken.nl:16265", "https://nodes.thetangle.org:443", "http://iota1.heidger.eu:14265", "https://nodes.iota.cafe:443", "https://potato.iotasalad.org:14265", "https://durian.iotasalad.org:14265", "https://turnip.iotasalad.org:14265", "https://nodes.iota.fm:443", "https://tuna.iotasalad.org:14265", "https://iotanode2.jlld.at:443", "https://node.iota.moe:443", "https://wallet1.iota.town:443", "https://wallet2.iota.town:443", "http://node03.iotatoken.nl:15265", "https://node.iota-tangle.io:14265", "https://pow4.iota.community:443", "https://dyn.tangle-nodes.com:443", "https://pow5.iota.community:443", }, 5000), new PoWSrvService()); var bundle = new Bundle(); bundle.AddTransfer( new Transfer { Address = new Address(Hash.Empty.Value), Tag = new Tag("MYCSHARPPI"), Timestamp = Timestamp.UnixSecondsTimestamp, Message = TryteString.FromUtf8String("Hello from PiDiver #1!") }); bundle.AddTransfer( new Transfer { Address = new Address(Hash.Empty.Value), Tag = new Tag("MYCSHARPPI"), Timestamp = Timestamp.UnixSecondsTimestamp, Message = TryteString.FromUtf8String("Hello from PiDiver #2!") }); bundle.Finalize(); bundle.Sign(); repository.SendTrytes(bundle.Transactions, 1); Console.WriteLine("Done"); Console.ReadKey(); }