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); }
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)); }
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); } } }
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); }
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()); }
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); }