private TransactionPayload BuildTransactionPayload(Dictionary <UTXOInput, Ed25519Seed> inputs, List <TransferOutput> outputs, string indexationKey, string data) { var mappedOutputs = outputs.Select(output => new SigLockedOutput(output.Receiver.DustAllowed ? SigLockedOutput.SigLockedDustAllowanceOutput : SigLockedOutput.SigLockedSingleOutputType) { Address = output.Receiver, Amount = output.Amount }) .ToDictionary(mappedOutput => mappedOutput, mappedOutput => mappedOutput.Serialize().ToHex()) .OrderBy(m => m.Value).ToDictionary(m => m.Key, m => m.Value); var mappedInputs = inputs.Select(input => new Tuple <UTXOInput, Ed25519Seed, string>(input.Key, input.Value, input.Key.Serialize().ToHex())) .OrderBy(i => i.Item3).ToList(); var transactionEssence = new TransactionEssence { Inputs = mappedInputs.Select(i => i.Item1).ToList(), Outputs = mappedOutputs.Select(o => o.Key).ToList(), Payload = !string.IsNullOrEmpty(indexationKey) ? new IndexationPayload { Index = indexationKey.ToHex(), Data = data.ToHex() } : null }; var transactionEssenceHash = transactionEssence.CalculateHash(); var unlockBlocks = new List <UnlockBlock>(); var addressToUnlockBlocks = new Dictionary <string, short>(); foreach (var(_, seed, _) in mappedInputs) { var addressPublicKey = seed.KeyPair.PublicKey.ToHex(); if (addressToUnlockBlocks.Any(t => t.Key == addressPublicKey)) { unlockBlocks.Add(new ReferenceUnlockBlock { Reference = addressToUnlockBlocks.First(t => t.Key == addressPublicKey).Value }); } else { unlockBlocks.Add(new SignatureUnlockBlock { Signature = Ed25519.Sign(transactionEssenceHash, seed) }); addressToUnlockBlocks.Add(addressPublicKey, (short)(unlockBlocks.Count - 1)); } } return(new TransactionPayload { Essence = transactionEssence, UnlockBlocks = unlockBlocks }); }
public void TestTransactionHashGeneration() { var expected = "41e3c1329ffb610aa30587e9fd6ca3ea3367a684ae20ee5d1cfacc3b6226584c"; var essence = new TransactionEssence { Inputs = new List <UTXOInput> { new UTXOInput { TransactionId = "c08141e6f09d8da0c7d5604e3e3bab20731948c120af42d58826817eaec9d186", TransactionOutputIndex = 0 } }, Outputs = new List <SigLockedOutput> { new SigLockedOutput { Amount = 1000, Address = new Ed25519Address { Address = "3f8530482fd6d0e3a198c327f5ce0423f2eb9e22be8c3ab0554d081467b20a5b" } } }, Payload = new IndexationPayload { Index = "746573740a", Data = "746573740a" } }; var actual = essence.CalculateHash().ToHex(); Assert.AreEqual(expected, actual); }