コード例 #1
0
 public void Finish()
 {
     if (_Marker != null)
     {
         var txout = EnsureMarkerInserted();
         txout.ScriptPubKey = _Marker.GetScript();
     }
 }
コード例 #2
0
ファイル: ColoredCoinsTests.cs プロジェクト: georgepinca/src
        public void CanParseColorMarker()
        {
            var         script = new Script(Encoders.Hex.DecodeData("6a104f41010003ac0200e58e260412345678"));
            ColorMarker marker = ColorMarker.TryParse(script);

            Assert.NotNull(marker);
            Assert.Equal(1, marker.Version);
            Assert.Equal(3, marker.Quantities.Length);
            Assert.True(marker.Quantities.SequenceEqual(new ulong[] { 300, 0, 624485 }));
            Assert.True(marker.Metadata.SequenceEqual(new byte[] { 0x12, 0x34, 0x56, 0x78 }));
            Assert.Equal(script.ToString(), marker.GetScript().ToString());
        }
コード例 #3
0
        public void AggregateOutputs(Transaction tr)
        {
            var finalOutputs = new Dictionary <string, TxOut>();

            var marker    = ColorMarker.Get(tr);
            var quantites = new Dictionary <string, ulong>();

            foreach (var trOutput in tr.Outputs.AsIndexedOutputs().Skip(marker == null ? 0 : 1))
            {
                var key = trOutput.TxOut.ScriptPubKey.ToHex();

                if (finalOutputs.ContainsKey(key))
                {
                    finalOutputs[key].Value += trOutput.TxOut.Value;
                    if (marker != null && marker.Quantities.Length >= trOutput.N)
                    {
                        quantites[key] += marker.Quantities[(int)trOutput.N - 1];
                    }
                }
                else
                {
                    finalOutputs[key] = trOutput.TxOut;
                    if (marker != null && marker.Quantities.Length >= trOutput.N)
                    {
                        quantites[key] = marker.Quantities[(int)trOutput.N - 1];
                    }
                }
            }
            tr.Outputs.Clear();

            var outputs = finalOutputs.ToList();

            if (marker != null)
            {
                var newMarker = new ColorMarker();
                newMarker.Quantities = outputs.Select(o => quantites.ContainsKey(o.Key) ? quantites[o.Key] : 0).ToArray();
                tr.Outputs.Add(new TxOut()
                {
                    ScriptPubKey = newMarker.GetScript(),
                    Value        = Money.Zero
                });
            }
            tr.Outputs.AddRange(outputs.Select(o => o.Value));
        }
コード例 #4
0
ファイル: ColoredCoinsTests.cs プロジェクト: georgepinca/src
        public void CanParseColorMarker2()
        {
            string[] invalidMarkers =
            {
                "6a114f41010003ac0200e58e26041234567800",         //Useless bytes at the end of the marker
                "6a4de803116a104f41010003ac0200e58e260412345678", //Invalid push consume a marker
                "6a056a104f41010003ac0200e58e260412345678",       //valid push consume a marker
            };

            foreach (Script script in invalidMarkers.Select(m => new Script(Encoders.Hex.DecodeData(m))))
            {
                ColorMarker marker = ColorMarker.TryParse(script);
                Assert.Null(marker);
            }
            string[] validMarkers =
            {
                "6a104f41010003ac0200e58e260412345678",                                   //One push
                "6a104f41010003ac0200e58e260412345678104f41010003ac0200e58e260412345678", //Two push
                "6a576e104f41010003ac0200e58e26041234567868",                             //Garbage push
                "6a576e104f41010003ac0200e58e2604123456786811",                           //Invalid push at the end
            };

            foreach (Script script in validMarkers.Select(m => new Script(Encoders.Hex.DecodeData(m))))
            {
                ColorMarker marker = ColorMarker.TryParse(script);
                Assert.NotNull(marker);
            }

            Transaction tx = this.networkMain.CreateTransaction();

            tx.Outputs.Add(new TxOut(Money.Zero, new Script(Encoders.Hex.DecodeData("6a114f41010003f00100e58e26041234567800104f41010003f00100e58e260412345678"))));
            tx.Outputs.Add(new TxOut(Money.Zero, new Script(Encoders.Hex.DecodeData("6a104f41010003ac0200e58e260412345678"))));
            ColorMarker marker2 = ColorMarker.TryParse(tx);

            Assert.Null(marker2); //No input
            tx.Inputs.Add(new TxIn());
            marker2 = ColorMarker.TryParse(tx);
            Assert.Null(marker2); //Coinbase
            tx.Inputs[0].PrevOut = new OutPoint(new uint256(1), 0);
            marker2 = ColorMarker.TryParse(tx);
            Assert.Equal("6a104f41010003f00100e58e260412345678", marker2.GetScript().ToHex());
        }
コード例 #5
0
ファイル: ColoredCoinsTests.cs プロジェクト: georgepinca/src
        public void CanColorizeOutputs()
        {
            ColoredCoinTester tester = CreateTester(this.networkMain, "CanColorizeIssuanceTransaction");

            ColoredTransaction colored1 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);

            Assert.True(colored1.Inputs.Count == 0);
            Assert.True(colored1.Issuances.Count == 1);
            Assert.True(colored1.Transfers.Count == 0);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored1.Issuances[0].Asset.Id.GetWif(this.networkMain).ToString());

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            ColoredTransaction colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);

            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Inputs[0].Asset == colored1.Issuances[0].Asset);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored2.Transfers[0].Asset.Id.GetWif(this.networkMain).ToString());

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            Transaction tx = tester.Repository.Transactions.Get(tester.TestedTxId);

            //If there are less items in the  asset quantity list  than the number of colorable outputs (all the outputs except the marker output), the outputs in excess receive an asset quantity of zero.
            tx.Outputs.Add(new TxOut());
            tx.Outputs.Add(new TxOut());
            tx.Outputs.Add(new TxOut());
            tester.TestedTxId = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Inputs[0].Asset == colored1.Issuances[0].Asset);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            Assert.Equal("Af59wop4VJjXk2DAzoX9scAUCcAsghPHFX", colored2.Transfers[0].Asset.Id.GetWif(this.networkMain).ToString());
            AssetMoney[] destroyed = colored2.GetDestroyedAssets();
            Assert.True(destroyed.Length == 0);

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are more items in the  asset quantity list  than the number of colorable outputs, the transaction is deemed invalid, and all outputs are uncolored.
            ColorMarker payload = tx.GetColoredMarker();

            payload.Quantities         = payload.Quantities.Concat(new ulong[] { 1, 2 }).ToArray();
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            Assert.False(tx.HasValidColoredMarker());
            tester.TestedTxId = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If the marker output is malformed, the transaction is invalid, and all outputs are uncolored.
            tx.Outputs[0].ScriptPubKey = new Script();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are less asset units in the input sequence than in the output sequence, the transaction is considered invalid and all outputs are uncolored.
            payload = tx.GetColoredMarker();
            payload.Quantities[0]      = 1001;
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 0);

            tester = CreateTester(this.networkMain, "CanColorizeTransferTransaction");
            tx     = tester.Repository.Transactions.Get(tester.TestedTxId);
            //If there are more asset units in the input sequence than in the output sequence, the transaction is considered valid
            payload = tx.GetColoredMarker();
            payload.Quantities[0]      = 999;
            tx.Outputs[0].ScriptPubKey = payload.GetScript();
            tester.TestedTxId          = tx.GetHash();
            tester.Repository.Transactions.Put(tester.TestedTxId, tx);
            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, tester.Repository);
            Assert.True(colored2.Inputs.Count == 1);
            Assert.True(colored2.Issuances.Count == 0);
            Assert.True(colored2.Transfers.Count == 2);
            destroyed = colored2.GetDestroyedAssets();
            Assert.True(destroyed.Length == 1);
            Assert.True(destroyed[0].Quantity == 1);
            Assert.True(destroyed[0].Id == colored2.Inputs[0].Asset.Id);

            //Verify that FetchColor update the repository
            var persistent = new NoSqlColoredTransactionRepository(KnownNetworks.Main, tester.Repository.Transactions, new InMemoryNoSqlRepository(KnownNetworks.Main));

            colored2 = ColoredTransaction.FetchColors(tester.TestedTxId, persistent);
            Assert.NotNull(persistent.Get(tester.TestedTxId));

            //Verify cached loadbulk correctly
            var cached = new CachedColoredTransactionRepository(persistent);

            persistent.Put(tester.TestedTxId, null);
            cached.WriteThrough = false;
            colored2            = ColoredTransaction.FetchColors(tester.TestedTxId, cached);
            cached.ReadThrough  = false;
            Assert.Null(cached.Get(tester.TestedTxId));            //Should not have written in the cache (cache outdated, thinking it is still null)
            Assert.NotNull(persistent.Get(tester.TestedTxId));     //But should have written in the inner repository
            Assert.NotNull(cached.Get(tx.Inputs[0].PrevOut.Hash)); //However, the previous transaction should have been loaded by loadbulk via ReadThrough
        }