예제 #1
0
        private BlockBase CreateTransferAssetToUtxoBlock(byte[][] assetIds, int index, ulong tagId, ConfidentialAccount receiver, byte[] sk = null)
        {
            byte[] assetId = assetIds[index];

            byte[]  secretKey       = sk ?? ConfidentialAssetsHelper.GetRandomSeed();
            byte[]  transactionKey  = ConfidentialAssetsHelper.GetTrancationKey(secretKey);
            byte[]  destinationKey  = ConfidentialAssetsHelper.GetDestinationKey(secretKey, receiver.PublicViewKey, receiver.PublicSpendKey);
            byte[]  blindingFactor  = ConfidentialAssetsHelper.GetRandomSeed();
            byte[]  assetCommitment = ConfidentialAssetsHelper.GetAssetCommitment(assetId, blindingFactor);
            ulong[] assetAmounts    = new ulong[assetIds.Length];
            for (int i = 0; i < assetAmounts.Length; i++)
            {
                assetAmounts[i] = 1;
            }

            TransferAssetToUtxoBlock transferAssetToUtxoBlock = new TransferAssetToUtxoBlock
            {
                TagId                = tagId,
                AssetIds             = assetIds,
                AssetAmounts         = assetAmounts,
                TransactionPublicKey = transactionKey,
                DestinationKey       = destinationKey,
                AssetId              = assetId,
                AssetCommitment      = assetCommitment,
                SurjectionProof      = ConfidentialAssetsHelper.CreateNewIssuanceSurjectionProof(assetCommitment, assetIds, index, blindingFactor),
                EcdhTuple            = ConfidentialAssetsHelper.CreateEcdhTupleCA(blindingFactor, assetId, secretKey, receiver.PublicViewKey)
            };

            FillHeightInfo(transferAssetToUtxoBlock);
            FillSyncData(transferAssetToUtxoBlock);
            FillRawData(transferAssetToUtxoBlock);

            return(transferAssetToUtxoBlock);
        }
예제 #2
0
        public bool SendAssetToUtxo(byte[][] assetIds, int index, ulong tagId, ConfidentialAccount receiver, byte[] sk = null)
        {
            TransferAssetToUtxoBlock block = (TransferAssetToUtxoBlock)CreateTransferAssetToUtxoBlock(assetIds, index, tagId, receiver, sk);
            BlockBase registerBlock        = CreateRegisterBlock(block, block.DestinationKey);

            return(_networkAdapter.SendTransaction(block, registerBlock));
        }
예제 #3
0
        private void ProcessTransferAssetsToUtxo(TransferAssetToUtxoBlock block, ulong registryCombinedBlockHeight)
        {
            if (_clientState.IsConfidential())
            {
                bool isToMe = ConfidentialAssetsHelper.IsDestinationKeyMine(block.DestinationKey, block.TransactionPublicKey, _clientState.GetSecretViewKey(), _clientState.GetPublicSpendKey());

                if (isToMe)
                {
                    byte[] otsk    = ConfidentialAssetsHelper.GetOTSK(block.TransactionPublicKey, _clientState.GetSecretViewKey(), _clientState.GetSecretSpendKey());
                    byte[] assetId = ConfidentialAssetsHelper.GetAssetIdFromEcdhTupleCA(block.EcdhTuple, block.TransactionPublicKey, _clientState.GetSecretViewKey());
                    _dataAccessService.StoreUtxoUnspentOutputs(block.SyncBlockHeight, registryCombinedBlockHeight, block.BlockType,
                                                               block.RawData.Span, block.TransactionPublicKey, ConfidentialAssetsHelper.GenerateKeyImage(otsk), block.TagId, block.AssetCommitment, block.DestinationKey, 1, assetId);
                }
                else
                {
                    _dataAccessService.StoreUtxoOutput(block.TagId, block.AssetCommitment, block.DestinationKey);
                }
            }
        }
예제 #4
0
        public void TransferAssetToUtxoBlockSerializerTest()
        {
            ulong tagId           = 113;
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryBuilder.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = BinaryBuilder.GetDefaultHash(1234);
            byte[] body;

            ulong uptodateFunds = 10001;

            byte[] transactionPublicKey = CryptoHelper.GetRandomSeed();
            byte[] destinationKey       = CryptoHelper.GetRandomSeed();
            byte[] assetId         = CryptoHelper.GetRandomSeed();
            byte[] assetCommitment = CryptoHelper.GetRandomSeed();
            uint   assetsCount     = 10;

            byte[][] assetIds         = new byte[assetsCount][];
            ulong[]  assetAmounts     = new ulong[assetsCount];
            byte[][] assetCommitments = new byte[assetsCount][];
            byte[]   e    = CryptoHelper.GetRandomSeed();
            byte[][] s    = new byte[assetsCount][];
            byte[]   mask = CryptoHelper.GetRandomSeed();

            Random random = new Random();

            for (int i = 0; i < assetsCount; i++)
            {
                assetIds[i]         = CryptoHelper.GetRandomSeed();
                assetAmounts[i]     = (ulong)random.Next();
                assetCommitments[i] = CryptoHelper.GetRandomSeed();
                s[i] = CryptoHelper.GetRandomSeed();
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(tagId);
                    bw.Write(uptodateFunds);
                    bw.Write(assetsCount);

                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetIds[i]);
                    }

                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetAmounts[i]);
                    }

                    bw.Write(destinationKey);
                    bw.Write(transactionPublicKey);
                    bw.Write(assetId);
                    bw.Write(assetCommitment);
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetCommitments[i]);
                    }
                    bw.Write(e);
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(s[i]);
                    }
                    bw.Write(mask);
                    bw.Write(assetId);
                }

                body = ms.ToArray();
            }

            byte[] expectedPacket = BinaryBuilder.GetSignedPacket(PacketType.Transactional, syncBlockHeight, nonce, powHash, version,
                                                                  BlockTypes.Transaction_TransferAssetsToUtxo, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            TransferAssetToUtxoBlock block = new TransferAssetToUtxoBlock
            {
                SyncBlockHeight      = syncBlockHeight,
                Nonce                = nonce,
                PowHash              = powHash,
                BlockHeight          = blockHeight,
                HashPrev             = prevHash,
                TagId                = tagId,
                UptodateFunds        = uptodateFunds,
                AssetIds             = assetIds,
                AssetAmounts         = assetAmounts,
                DestinationKey       = destinationKey,
                TransactionPublicKey = transactionPublicKey,
                AssetId              = assetId,
                AssetCommitment      = assetCommitment,
                SurjectionProof      = new SurjectionProof
                {
                    AssetCommitments = assetCommitments,
                    Rs = new BorromeanRingSignature
                    {
                        E = e,
                        S = s
                    }
                },
                EcdhTuple = new EcdhTupleCA {
                    Mask = mask, AssetId = assetId
                }
            };

            TransferAssetToUtxoBlockSerializer serializer = new TransferAssetToUtxoBlockSerializer(_cryptoService, _identityKeyProvidersRegistry, _hashCalculationRepository);

            serializer.Initialize(block);

            byte[] actualPacket = serializer.GetBytes();

            Assert.Equal(expectedPacket, actualPacket);
        }
예제 #5
0
        public void TransferAssetToUtxoBlockParserTest()
        {
            ulong tagId           = 147;
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryBuilder.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] prevHash = BinaryBuilder.GetDefaultHash(1234);
            byte[] body;

            ulong uptodateFunds = 10001;

            byte[] transactionPublicKey = CryptoHelper.GetRandomSeed();
            byte[] destinationKey       = CryptoHelper.GetRandomSeed();
            byte[] assetId         = CryptoHelper.GetRandomSeed();
            byte[] assetCommitment = CryptoHelper.GetRandomSeed();
            uint   assetsCount     = 10;

            byte[][] assetIds         = new byte[assetsCount][];
            ulong[]  assetAmount      = new ulong[assetsCount];
            byte[][] assetCommitments = new byte[assetsCount][];
            byte[]   e    = CryptoHelper.GetRandomSeed();
            byte[][] s    = new byte[assetsCount][];
            byte[]   mask = CryptoHelper.GetRandomSeed();

            Random random = new Random();

            for (int i = 0; i < assetsCount; i++)
            {
                assetIds[i]         = CryptoHelper.GetRandomSeed();
                assetAmount[i]      = 1;
                assetCommitments[i] = CryptoHelper.GetRandomSeed();
                s[i] = CryptoHelper.GetRandomSeed();
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(tagId);
                    bw.Write(uptodateFunds);
                    bw.Write(assetsCount);
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetIds[i]);
                    }
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetAmount[i]);
                    }
                    bw.Write(destinationKey);
                    bw.Write(transactionPublicKey);
                    bw.Write(assetId);
                    bw.Write(assetCommitment);
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(assetCommitments[i]);
                    }
                    bw.Write(e);
                    for (int i = 0; i < assetsCount; i++)
                    {
                        bw.Write(s[i]);
                    }
                    bw.Write(mask);
                    bw.Write(assetId);
                }

                body = ms.ToArray();
            }

            byte[] packet = BinaryBuilder.GetSignedPacket(PacketType.Transactional, syncBlockHeight, nonce, powHash, version,
                                                          BlockTypes.Transaction_TransferAssetsToUtxo, blockHeight, prevHash, body, _privateKey, out byte[] expectedSignature);

            TransferAssetToUtxoBlockParser parser = new TransferAssetToUtxoBlockParser(_hashCalculationRepository, _identityKeyProvidersRegistry);
            TransferAssetToUtxoBlock       block  = (TransferAssetToUtxoBlock)parser.Parse(packet);

            Assert.Equal(syncBlockHeight, block.SyncBlockHeight);
            Assert.Equal(nonce, block.Nonce);
            Assert.Equal(powHash, block.PowHash);
            Assert.Equal(version, block.Version);
            Assert.Equal(blockHeight, block.BlockHeight);
            Assert.Equal(prevHash, block.HashPrev);
            Assert.Equal(uptodateFunds, block.UptodateFunds);
            Assert.Equal(destinationKey, block.DestinationKey);
            Assert.Equal(transactionPublicKey, block.TransactionPublicKey);
            Assert.Equal(assetId, block.AssetId);
            Assert.Equal(assetCommitment, block.AssetCommitment);
            Assert.Equal(assetsCount, (uint)block.SurjectionProof.AssetCommitments.Length);

            for (int i = 0; i < assetsCount; i++)
            {
                Assert.Equal(assetCommitments[i], block.SurjectionProof.AssetCommitments[i]);
                Assert.Equal(s[i], block.SurjectionProof.Rs.S[i]);
            }
            Assert.Equal(e, block.SurjectionProof.Rs.E);
            Assert.Equal(mask, block.EcdhTuple.Mask);
            Assert.Equal(assetId, block.EcdhTuple.AssetId);
            Assert.Equal(_publicKey, block.Signer.Value.ToArray());
            Assert.Equal(expectedSignature, block.Signature.ToArray());
        }
예제 #6
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, uint assetsCount, out TransactionalBlockBase transactionalBlockBase)
        {
            TransactionalBlockBase block = null;

            if (version == 1)
            {
                int readBytes = 0;

                byte[] destinationKey = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                byte[] transactionPublicKey = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                byte[] assetId = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                byte[] assetCommitment = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                byte[][] assetCommitments = new byte[assetsCount][];
                for (int i = 0; i < assetsCount; i++)
                {
                    assetCommitments[i] = spanBody.Slice(readBytes, 32).ToArray();
                    readBytes          += 32;
                }

                byte[] e = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                byte[][] s = new byte[assetsCount][];
                for (int i = 0; i < assetsCount; i++)
                {
                    s[i]       = spanBody.Slice(readBytes, 32).ToArray();
                    readBytes += 32;
                }

                byte[] mask = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;
                byte[] asset = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                SurjectionProof surjectionProof = new SurjectionProof
                {
                    AssetCommitments = assetCommitments,
                    Rs = new BorromeanRingSignature
                    {
                        E = e,
                        S = s
                    }
                };

                block = new TransferAssetToUtxoBlock
                {
                    TransactionPublicKey = transactionPublicKey,
                    DestinationKey       = destinationKey,
                    AssetId         = assetId,
                    AssetCommitment = assetCommitment,
                    SurjectionProof = surjectionProof,
                    EcdhTuple       = new EcdhTupleCA
                    {
                        Mask    = mask,
                        AssetId = asset
                    }
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }