コード例 #1
0
        public bool TryReadValue(UInt256 blockHash, out ImmutableArray<Transaction> blockTransactions)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT TxHash, TxBytes
                    FROM BlockTransactions
                    WHERE BlockHash = @blockHash
                    ORDER BY TxIndex ASC";

                cmd.Parameters.SetValue("@blockHash", FbDbType.Char, FbCharset.Octets, 32).Value = blockHash.ToDbByteArray();

                using (var reader = cmd.ExecuteReader())
                {
                    var blockTransactionsBuilder = ImmutableArray.CreateBuilder<Transaction>();

                    while (reader.Read())
                    {
                        var txHash = reader.GetUInt256(0);
                        var txBytes = reader.GetBytes(1);

                        blockTransactionsBuilder.Add(StorageEncoder.DecodeTransaction(txBytes.ToMemoryStream(), txHash));
                    }

                    blockTransactions = blockTransactionsBuilder.ToImmutable();
                    return blockTransactions.Length > 0;
                }
            }
        }
コード例 #2
0
        public PublicKeyHashAddress(ImmutableArray<byte> publicKeyHashBytes)
        {
            this.publicKeyHashBytes = publicKeyHashBytes;

            var outputScript = new PayToPublicKeyHashBuilder().CreateOutputFromPublicKeyHash(publicKeyHashBytes.ToArray());
            this.outputScriptHash = new UInt256(SHA256Static.ComputeHash(outputScript));
        }
コード例 #3
0
        public bool TryReadValue(UInt256 blockHash, out ImmutableArray<Transaction> blockTransactions)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT MinTxIndex, MaxTxIndex, TxChunkBytes
                    FROM BlockTransactionsChunked
                    WHERE BlockHash = @blockHash
                    ORDER BY MinTxIndex ASC";

                cmd.Parameters.SetValue("@blockHash", SqlDbType.Binary, 32).Value = blockHash.ToDbByteArray();

                using (var reader = cmd.ExecuteReader())
                {
                    var blockTransactionsBuilder = ImmutableArray.CreateBuilder<Transaction>();

                    while (reader.Read())
                    {
                        var minTxIndex = reader.GetInt32(0);
                        var maxTxIndex = reader.GetInt32(1);
                        var txChunkBytes = reader.GetBytes(2);

                        var txChunkStream = txChunkBytes.ToMemoryStream();
                        for (var i = minTxIndex; i <= maxTxIndex; i++)
                        {
                            blockTransactionsBuilder.Add(StorageEncoder.DecodeTransaction(txChunkStream));
                        }
                    }

                    blockTransactions = blockTransactionsBuilder.ToImmutable();
                    return blockTransactions.Length > 0;
                }
            }
        }
コード例 #4
0
        public bool ContainsChainedHeader(UInt256 blockHash)
        {
            var key = MakeHeaderKey(blockHash);

            Slice ignore;
            return db.TryGet(new ReadOptions(), key, out ignore);
        }
コード例 #5
0
ファイル: ScriptEngine.cs プロジェクト: cole2295/BitSharp
        public bool VerifyScript(UInt256 blockHash, int txIndex, byte[] scriptPubKey, Transaction tx, int inputIndex, byte[] script)
        {
            if (logger.IsTraceEnabled)
                logger.Trace(
@"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Verifying script for block {0}, transaction {1}, input {2}
{3}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                    , blockHash, txIndex, inputIndex, script.ToArray().ToHexDataString());

            Stack stack, altStack;
            if (
                ExecuteOps(scriptPubKey, tx, inputIndex, script, out stack, out altStack)
                && stack.Count == 1 && altStack.Count == 0)
            {
                var success = stack.PeekBool(); //TODO Pop? does it matter?

                // Additional validation for spend-to-script-hash transactions:
                //TODO

                return success;
            }
            else
            {
                return false;
            }
        }
コード例 #6
0
ファイル: DataCalculator.cs プロジェクト: cole2295/BitSharp
        public static UInt32 TargetToBits(UInt256 target)
        {
            // to get the powerPart: take the log in base 2, round up to 8 to respect byte boundaries, and then remove 24 to represent 3 bytes of precision
            var log = Math.Ceiling(UInt256.Log(target, 2) / 8) * 8 - 24;
            var powerPart = (byte)(log / 8 + 3);

            // determine the multiplier based on the powerPart
            var multiplier = BigInteger.Pow(2, 8 * (powerPart - 3));

            // to get multiplicand: divide the target by the multiplier
            //TODO
            var multiplicandBytes = ((BigInteger)target / (BigInteger)multiplier).ToByteArray();
            Debug.Assert(multiplicandBytes.Length == 3 || multiplicandBytes.Length == 4);

            // this happens when multipicand would be greater than 0x7fffff
            // TODO need a better explanation comment
            if (multiplicandBytes.Last() == 0)
            {
                multiplicandBytes = multiplicandBytes.Skip(1).ToArray();
                powerPart++;
            }

            // construct the bits representing the powerPart and multiplicand
            var bits = Bits.ToUInt32(multiplicandBytes.Concat(powerPart).ToArray());
            return bits;
        }
コード例 #7
0
 public LevelDBBlockchain()
 {
     Slice value;
     db = DB.Open(Settings.Default.DataDirectoryPath);
     if (db.TryGet(ReadOptions.Default, SliceBuilder.Begin(DataEntryPrefix.CFG_Initialized), out value) && value.ToBoolean())
     {
         value = db.Get(ReadOptions.Default, SliceBuilder.Begin(DataEntryPrefix.SYS_CurrentBlock));
         this.current_block = new UInt256(value.ToArray().Take(32).ToArray());
         this.current_height = BitConverter.ToUInt32(value.ToArray(), 32);
     }
     else
     {
         WriteBatch batch = new WriteBatch();
         ReadOptions options = new ReadOptions { FillCache = false };
         using (Iterator it = db.NewIterator(options))
         {
             for (it.SeekToFirst(); it.Valid(); it.Next())
             {
                 batch.Delete(it.Key());
             }
         }
         batch.Put(SliceBuilder.Begin(DataEntryPrefix.CFG_Version), 0);
         db.Write(WriteOptions.Default, batch);
         AddBlockToChain(GenesisBlock);
         db.Put(WriteOptions.Default, SliceBuilder.Begin(DataEntryPrefix.CFG_Initialized), true);
     }
     thread_persistence = new Thread(PersistBlocks);
     thread_persistence.Name = "LevelDBBlockchain.PersistBlocks";
     thread_persistence.Start();
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
 }
コード例 #8
0
 public bool ContainsChainedHeader(UInt256 blockHash)
 {
     using (var txn = this.jetInstance.BeginTransaction(TransactionBeginFlags.ReadOnly))
     {
         return txn.ContainsKey(blockHeadersTableId, DbEncoder.EncodeUInt256(blockHash));
     }
 }
コード例 #9
0
ファイル: DataCalculator.cs プロジェクト: pmlyon/BitSharp
        public static uint ToCompact(UInt256 value, bool negative = false)
        {
            var size = (HighBit(value) + 7) / 8;
            var compact = 0U;

            if (size <= 3)
            {
                compact = (uint)(value.Part4 << 8 * (3 - size));
            }
            else
            {
                value >>= 8 * (size - 3);
                compact = (uint)(value.Part4);
            }

            // The 0x00800000 bit denotes the sign.
            // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
            if ((compact & 0x00800000) != 0)
            {
                compact >>= 8;
                size++;
            }

            Debug.Assert((compact & ~0x007fffff) == 0);
            Debug.Assert(size < 256);

            compact |= (uint)(size << 24);
            if (negative && (compact & 0x007fffff) != 0)
                compact |= 0x00800000;

            return compact;
        }
コード例 #10
0
ファイル: BlockchainKey.cs プロジェクト: holinov/BitSharp
        public BlockchainKey(Guid guid, UInt256 rootBlockHash)
        {
            this._guid = guid;
            this._rootBlockHash = rootBlockHash;

            this.hashCode = guid.GetHashCode() ^ rootBlockHash.GetHashCode();
        }
コード例 #11
0
ファイル: SpentTx.cs プロジェクト: cole2295/BitSharp
 public SpentTx(UInt256 txHash, int confirmedBlockIndex, int txIndex, int outputCount)
 {
     TxHash = txHash;
     ConfirmedBlockIndex = confirmedBlockIndex;
     TxIndex = txIndex;
     OutputCount = outputCount;
 }
コード例 #12
0
 void ISerializable.Deserialize(BinaryReader reader)
 {
     this.AssetId = reader.ReadSerializable<UInt256>();
     this.Value = reader.ReadSerializable<Fixed8>();
     if (Value <= Fixed8.Zero) throw new FormatException();
     this.ScriptHash = reader.ReadSerializable<UInt160>();
 }
コード例 #13
0
 public bool ContainsBlock(UInt256 blockHash)
 {
     using (var txn = this.jetInstance.BeginTransaction(TransactionBeginFlags.ReadOnly))
     {
         return txn.ContainsKey(blocksTableId, DbEncoder.EncodeBlockHashTxIndex(blockHash, 0));
     }
 }
コード例 #14
0
 public bool TryAddBlockTransactions(UInt256 blockHash, IEnumerable<EncodedTx> blockTxes)
 {
     return this.allBlockTxNodes.TryAdd(blockHash,
         ImmutableSortedDictionary.CreateRange<int, BlockTxNode>(
             blockTxes.Select((tx, txIndex) =>
                 new KeyValuePair<int, BlockTxNode>(txIndex, new BlockTx(txIndex, tx)))));
 }
コード例 #15
0
 public MerkleTreePruningCursor(UInt256 blockHash, LightningTransaction txn, LightningDatabase db, LightningCursor cursor)
 {
     this.blockHash = blockHash;
     this.db = db;
     this.txn = txn;
     this.cursor = cursor;
 }
コード例 #16
0
ファイル: RemoteSender.cs プロジェクト: holinov/BitSharp
        public async Task SendGetBlocks(ImmutableArray<UInt256> blockLocatorHashes, UInt256 hashStop)
        {
            var getBlocksPayload = Messaging.ConstructGetBlocksPayload(blockLocatorHashes, hashStop);
            var getBlocksMessage = Messaging.ConstructMessage("getblocks", NetworkEncoder.EncodeGetBlocksPayload(getBlocksPayload));

            await SendMessageAsync(getBlocksMessage);
        }
コード例 #17
0
        public bool TryReadValue(UInt256 txHash, out Transaction transaction)
        {
            using (var conn = this.OpenConnection())
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = @"
                    SELECT TxBytes
                    FROM BlockTransactions
                    WHERE TxHash = @txHash";

                cmd.Parameters.SetValue("@txHash", FbDbType.Char, FbCharset.Octets, 32).Value = txHash.ToDbByteArray();

                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        var txBytes = reader.GetBytes(0);

                        transaction = StorageEncoder.DecodeTransaction(txBytes.ToMemoryStream(), txHash);
                        return true;
                    }
                    else
                    {
                        transaction = default(Transaction);
                        return false;
                    }
                }
            }
        }
コード例 #18
0
ファイル: UInt256Test.cs プロジェクト: cole2295/BitSharp
        public void TestUInt256Sha256()
        {
            var expected = SHA256Static.ComputeDoubleHash(UInt256.ParseHex(TestData.HEX_STRING_64).ToByteArray());
            var actual = new UInt256(expected).ToByteArray();

            CollectionAssert.AreEqual(expected, actual);
        }
コード例 #19
0
ファイル: UtxoTest.cs プロジェクト: cole2295/BitSharp
        public void TestCanSpend_Spent()
        {
            // prepare utxo storage
            var chain = Chain.CreateForGenesisBlock(new FakeHeaders().GenesisChained());
            var unspentTransactions = ImmutableSortedDictionary.CreateBuilder<UInt256, UnspentTx>();

            // prepare spent output
            var txHash = new UInt256(0);
            unspentTransactions.Add(txHash, new UnspentTx(txHash, blockIndex: 0, txIndex: 0, txVersion: 0, isCoinbase: false, length: 1, state: OutputState.Spent));

            // prepare utxo
            var memoryStorage = new MemoryStorageManager(unspentTransactions: unspentTransactions.ToImmutable());
            var chainStateStorage = memoryStorage.OpenChainStateCursor().Item;
            chainStateStorage.BeginTransaction();
            chainStateStorage.ChainTip = chain.GenesisBlock;
            chainStateStorage.CommitTransaction();
            var utxo = new ChainState(chain, memoryStorage);

            // prepare output reference
            var prevTxOutput = new TxOutputKey(txHash, txOutputIndex: 0);

            // check if output can be spent
            var canSpend = utxo.CanSpend(prevTxOutput);

            // verify output cannot be spent
            Assert.IsFalse(canSpend);
        }
コード例 #20
0
 void ISerializable.Deserialize(BinaryReader reader)
 {
     this.PrevHash = reader.ReadSerializable<UInt256>();
     this.PrevIndex = reader.ReadUInt32();
     this.Script = reader.ReadBytes((int)reader.ReadVarInt());
     this.Sequence = reader.ReadUInt32();
 }
コード例 #21
0
ファイル: TxOutputKey.cs プロジェクト: ArsenShnurkov/BitSharp
        public TxOutputKey(UInt256 txHash, UInt32 txOutputIndex)
        {
            TxHash = txHash;
            TxOutputIndex = txOutputIndex;

            this.hashCode = txHash.GetHashCode() ^ txOutputIndex.GetHashCode();
        }
コード例 #22
0
        protected override List<uint> ScanHash_CryptoPP(MinerData md, UInt256 target)
        {
            uint nonce = (uint)md.nHashesDone;
            List<uint> results = new List<uint>(1);

            UInt256 hashResult = new UInt256();

            byte[] tmp = new byte[16 * 4];

            DateTime endLhutc = DateTime.UtcNow + new TimeSpan(0, 0, 1);
            long count = 0;
            while (true)
            {
                count++;
                Single(md, hashResult, nonce, tmp);

                var lastInt = BitConverter.ToInt32(hashResult.bytes, 7*4);
                if (lastInt == 0 && hashResult.CompareTo(target) < 0)
                    results.Add(nonce);

                nonce++;

                if (DateTime.UtcNow >= endLhutc || nonce == 0)
                    break;
            }

            md.nHashesDone += count;
            HashedSome(count);

            return results;
        }
コード例 #23
0
ファイル: TxKey.cs プロジェクト: holinov/BitSharp
        public TxKey(UInt256 blockHash, UInt32 txIndex, UInt256 txHash)
        {
            this._blockHash = blockHash;
            this._txIndex = txIndex;
            this._txHash = txHash;

            this.hashCode = blockHash.GetHashCode() ^ txIndex.GetHashCode() ^ txHash.GetHashCode();
        }
コード例 #24
0
ファイル: BlockProvider.cs プロジェクト: cole2295/BitSharp
        public Block GetBlock(UInt256 hash)
        {
            var name = hashNames[hash];
            if (name == null)
                return null;

            return GetEntry(name);
        }
コード例 #25
0
 public InventoryVector With(UInt32? Type = null, UInt256 Hash = null)
 {
     return new InventoryVector
     (
         Type ?? this.Type,
         Hash ?? this.Hash
     );
 }
コード例 #26
0
ファイル: DbEncoder.cs プロジェクト: ArsenShnurkov/BitSharp
        public static byte[] EncodeBlockHashTxIndex(UInt256 blockHash, int txIndex)
        {
            var blockHashTxIndexBytes = new byte[36];
            Buffer.BlockCopy(DbEncoder.EncodeUInt256(blockHash), 0, blockHashTxIndexBytes, 0, 32);
            Buffer.BlockCopy(DbEncoder.EncodeInt32(txIndex), 0, blockHashTxIndexBytes, 32, 4);

            return blockHashTxIndexBytes;
        }
コード例 #27
0
 public static GetBlocksPayload Create(IEnumerable<UInt256> hash_start, UInt256 hash_stop = null)
 {
     return new GetBlocksPayload
     {
         HashStart = hash_start.ToArray(),
         HashStop = hash_stop ?? UInt256.Zero
     };
 }
コード例 #28
0
ファイル: TxOutputKey.cs プロジェクト: knocte/BitSharp
        public TxOutputKey(UInt256 txHash, UInt32 txOutputIndex)
        {
            this._txHash = txHash;
            this._txOutputIndex = txOutputIndex;

            this.notDefault = true;
            this.hashCode = txHash.GetHashCode() ^ txOutputIndex.GetHashCode();
        }
コード例 #29
0
ファイル: UnspentTx.cs プロジェクト: ArsenShnurkov/BitSharp
 public UnspentTx(UInt256 txHash, int blockIndex, int txIndex, OutputStates outputStates)
 {
     TxHash = txHash;
     BlockIndex = blockIndex;
     TxIndex = txIndex;
     OutputStates = outputStates;
     IsFullySpent = OutputStates.All(x => x == OutputState.Spent);
 }
コード例 #30
0
ファイル: UnspentTx.cs プロジェクト: ArsenShnurkov/BitSharp
 public UnspentTx(UInt256 txHash, int blockIndex, int txIndex, int length, OutputState state)
 {
     TxHash = txHash;
     BlockIndex = blockIndex;
     TxIndex = txIndex;
     OutputStates = new OutputStates(length, state);
     IsFullySpent = state == OutputState.Spent;
 }
コード例 #31
0
 public UInt256 Calculate(UInt256 parentDifficulty, UInt256 parentTimestamp, UInt256 currentTimestamp, long blockNumber, bool parentHasUncles)
 {
     return(Wrapped.Calculate(parentDifficulty, parentTimestamp, currentTimestamp, blockNumber, parentHasUncles));
 }
コード例 #32
0
 public MinGasPriceTxFilter(UInt256 minGasPrice)
 {
     _minGasPrice = minGasPrice;
 }
コード例 #33
0
        public JSInput()
        {
            byte[] random_byte256 = new byte[32];
            using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(random_byte256);
            }
            key = new SpendingKey(new UInt256(random_byte256));

            note = new Note(key.address().a_pk, new Fixed8(0), UInt256.Random(), UInt256.Random(), UInt256.Random());

            witness = new byte[0];
            AssetID = new UInt256();
        }
コード例 #34
0
ファイル: NEP6Wallet.cs プロジェクト: MFChain/mfc-core
 public override Coin[] FindUnspentCoins(UInt256 asset_id, Fixed8 amount, UInt160[] from)
 {
     return(FindUnspentCoins(FindUnspentCoins(from).ToArray().Where(p => GetAccount(p.Output.ScriptHash).Contract.IsStandard), asset_id, amount) ?? base.FindUnspentCoins(asset_id, amount, from));
 }
コード例 #35
0
        private RelayResultReason OnNewBlock(Block block)
        {
            if (block.Index <= Height)
            {
                return(RelayResultReason.AlreadyExists);
            }
            if (block_cache.ContainsKey(block.Hash))
            {
                return(RelayResultReason.AlreadyExists);
            }
            if (block.Index - 1 >= header_index.Count)
            {
                AddUnverifiedBlockToCache(block);
                return(RelayResultReason.UnableToVerify);
            }
            if (block.Index == header_index.Count)
            {
                if (!block.Verify(currentSnapshot))
                {
                    return(RelayResultReason.Invalid);
                }
            }
            else
            {
                if (!block.Hash.Equals(header_index[(int)block.Index]))
                {
                    return(RelayResultReason.Invalid);
                }
            }
            if (block.Index == Height + 1)
            {
                Block        block_persist       = block;
                List <Block> blocksToPersistList = new List <Block>();
                while (true)
                {
                    blocksToPersistList.Add(block_persist);
                    if (block_persist.Index + 1 >= header_index.Count)
                    {
                        break;
                    }
                    UInt256 hash = header_index[(int)block_persist.Index + 1];
                    if (!block_cache.TryGetValue(hash, out block_persist))
                    {
                        break;
                    }
                }

                int blocksPersisted = 0;
                foreach (Block blockToPersist in blocksToPersistList)
                {
                    block_cache_unverified.Remove(blockToPersist.Index);
                    Persist(blockToPersist);

                    if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0, (15 - SecondsPerBlock))))
                    {
                        continue;
                    }
                    // Empirically calibrated for relaying the most recent 2 blocks persisted with 15s network
                    // Increase in the rate of 1 block per second in configurations with faster blocks

                    if (blockToPersist.Index + 100 >= header_index.Count)
                    {
                        system.LocalNode.Tell(new LocalNode.RelayDirectly {
                            Inventory = blockToPersist
                        });
                    }
                }
                SaveHeaderHashList();

                if (block_cache_unverified.TryGetValue(Height + 1, out LinkedList <Block> unverifiedBlocks))
                {
                    foreach (var unverifiedBlock in unverifiedBlocks)
                    {
                        Self.Tell(unverifiedBlock, ActorRefs.NoSender);
                    }
                    block_cache_unverified.Remove(Height + 1);
                }
            }
            else
            {
                block_cache.Add(block.Hash, block);
                if (block.Index + 100 >= header_index.Count)
                {
                    system.LocalNode.Tell(new LocalNode.RelayDirectly {
                        Inventory = block
                    });
                }
                if (block.Index == header_index.Count)
                {
                    header_index.Add(block.Hash);
                    using (Snapshot snapshot = GetSnapshot())
                    {
                        snapshot.Blocks.Add(block.Hash, new BlockState
                        {
                            SystemFeeAmount = 0,
                            TrimmedBlock    = block.Header.Trim()
                        });
                        snapshot.HeaderHashIndex.GetAndChange().Hash  = block.Hash;
                        snapshot.HeaderHashIndex.GetAndChange().Index = block.Index;
                        SaveHeaderHashList(snapshot);
                        snapshot.Commit();
                    }
                    UpdateCurrentSnapshot();
                }
            }
            return(RelayResultReason.Succeed);
        }
コード例 #36
0
 public MemoryChainStateStorage(UInt256 blockHash, ImmutableDictionary <UInt256, UnspentTx> unspentTransactions, ImmutableDictionary <TxOutputKey, TxOutput> unspentOutputs)
 {
     this.blockHash           = blockHash;
     this.unspentTransactions = unspentTransactions;
     this.unspentOutputs      = unspentOutputs;
 }
コード例 #37
0
 public bool TryGetTransaction(UInt256 txHash, out UnspentTx unspentTx)
 {
     return(this.unspentTransactions.TryGetValue(txHash, out unspentTx));
 }
コード例 #38
0
        public void TestVerifyWitnesses()
        {
            var     snapshot1 = Blockchain.Singleton.GetSnapshot().CreateSnapshot();
            UInt256 index1    = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01");

            BlocksAdd(snapshot1, index1, new TrimmedBlock()
            {
                Timestamp     = 1,
                PrevHash      = UInt256.Zero,
                MerkleRoot    = UInt256.Zero,
                ConsensusData = new ConsensusData(),
                Hashes        = new UInt256[1] {
                    UInt256.Zero
                },
                NextConsensus = UInt160.Zero,
                Witness       = new Witness()
                {
                    InvocationScript = new byte[0], VerificationScript = new byte[0]
                }
            });
            BlocksDelete(snapshot1, index1);
            Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(new Header()
            {
                PrevHash = index1
            }, snapshot1, 100));

            var          snapshot2 = Blockchain.Singleton.GetSnapshot();
            UInt256      index2    = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01");
            TrimmedBlock block2    = new TrimmedBlock()
            {
                Timestamp     = 2,
                PrevHash      = UInt256.Zero,
                MerkleRoot    = UInt256.Zero,
                ConsensusData = new ConsensusData(),
                Hashes        = new UInt256[1] {
                    UInt256.Zero
                },
                NextConsensus = UInt160.Zero,
                Witness       = new Witness()
                {
                    InvocationScript = new byte[0], VerificationScript = new byte[0]
                }
            };

            BlocksAdd(snapshot2, index2, block2);
            Header header2 = new Header()
            {
                PrevHash = index2, Witness = new Witness {
                    InvocationScript = new byte[0], VerificationScript = new byte[0]
                }
            };

            snapshot2.AddContract(UInt160.Zero, new ContractState());
            snapshot2.DeleteContract(UInt160.Zero);
            Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header2, snapshot2, 100));

            var          snapshot3 = Blockchain.Singleton.GetSnapshot();
            UInt256      index3    = UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01");
            TrimmedBlock block3    = new TrimmedBlock()
            {
                Timestamp     = 3,
                PrevHash      = UInt256.Zero,
                MerkleRoot    = UInt256.Zero,
                ConsensusData = new ConsensusData(),
                Hashes        = new UInt256[1] {
                    UInt256.Zero
                },
                NextConsensus = UInt160.Zero,
                Witness       = new Witness()
                {
                    InvocationScript = new byte[0], VerificationScript = new byte[0]
                }
            };

            BlocksAdd(snapshot3, index3, block3);
            Header header3 = new Header()
            {
                PrevHash = index3,
                Witness  = new Witness
                {
                    InvocationScript   = Array.Empty <byte>(),
                    VerificationScript = Array.Empty <byte>()
                }
            };

            snapshot3.AddContract(UInt160.Zero, new ContractState()
            {
                Nef = new NefFile {
                    Script = Array.Empty <byte>()
                },
                Hash     = Array.Empty <byte>().ToScriptHash(),
                Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature),
            });
            Assert.AreEqual(false, Neo.SmartContract.Helper.VerifyWitnesses(header3, snapshot3, 100));

            // Smart contract verification

            var contract = new ContractState()
            {
                Nef = new NefFile {
                    Script = "11".HexToBytes()
                },                                                                                                             // 17 PUSH1
                Hash     = "11".HexToBytes().ToScriptHash(),
                Manifest = TestUtils.CreateManifest("verify", ContractParameterType.Boolean, ContractParameterType.Signature), // Offset = 0
            };

            snapshot3.AddContract(contract.Hash, contract);
            var tx = new Nep17NativeContractExtensions.ManualWitness(contract.Hash)
            {
                Witnesses = new Witness[] { new Witness()
                                            {
                                                InvocationScript = Array.Empty <byte>(), VerificationScript = Array.Empty <byte>()
                                            } }
            };

            Assert.AreEqual(true, Neo.SmartContract.Helper.VerifyWitnesses(tx, snapshot3, 1000));
        }
コード例 #39
0
 private void BlocksDelete(DataCache snapshot, UInt256 hash)
 {
     snapshot.Delete(NativeContract.Ledger.CreateStorageKey(Prefix_BlockHash, hash));
     snapshot.Delete(NativeContract.Ledger.CreateStorageKey(Prefix_Block, hash));
 }
コード例 #40
0
 public static void BlocksAdd(DataCache snapshot, UInt256 hash, TrimmedBlock block)
 {
     snapshot.Add(NativeContract.Ledger.CreateStorageKey(Prefix_BlockHash, block.Index), new StorageItem(hash.ToArray(), true));
     snapshot.Add(NativeContract.Ledger.CreateStorageKey(Prefix_Block, hash), new StorageItem(block.ToArray(), true));
 }
コード例 #41
0
        private long Refund(long gasLimit, long unspentGas, TransactionSubstate substate, Address sender, UInt256 gasPrice, IReleaseSpec spec)
        {
            long spentGas = gasLimit;
            if (!substate.IsError)
            {
                spentGas -= unspentGas;
                long refund = substate.ShouldRevert ? 0 : Math.Min(spentGas / 2L, substate.Refund + substate.DestroyList.Count * RefundOf.Destroy);

                if (_logger.IsTrace) _logger.Trace("Refunding unused gas of " + unspentGas + " and refund of " + refund);
                _stateProvider.AddToBalance(sender, (ulong) (unspentGas + refund) * gasPrice, spec);
                spentGas -= refund;
            }

            return spentGas;
        }
コード例 #42
0
ファイル: InventoryVector.cs プロジェクト: radtek/BitSharp
 public InventoryVector(UInt32 Type, UInt256 Hash)
 {
     this.Type = Type;
     this.Hash = Hash;
 }
コード例 #43
0
 /// <summary>
 /// Broadcasts a serialized block over the NEO network.
 /// </summary>
 public UInt256 SubmitBlock(byte[] block)
 {
     return(UInt256.Parse(RpcSend("submitblock", block.ToHexString())["hash"].AsString()));
 }
コード例 #44
0
        private void button3_Click(object sender, EventArgs e)
        {
            string            s         = textBox2.Text;
            ContractParameter parameter = new ContractParameter();

            if (string.Equals(s, "true", StringComparison.OrdinalIgnoreCase))
            {
                parameter.Type  = ContractParameterType.Boolean;
                parameter.Value = true;
            }
            else if (string.Equals(s, "false", StringComparison.OrdinalIgnoreCase))
            {
                parameter.Type  = ContractParameterType.Boolean;
                parameter.Value = false;
            }
            else if (long.TryParse(s, out long num))
            {
                parameter.Type  = ContractParameterType.Integer;
                parameter.Value = num;
            }
            else if (s.StartsWith("0x"))
            {
                if (UInt160.TryParse(s, out UInt160 i160))
                {
                    parameter.Type  = ContractParameterType.Hash160;
                    parameter.Value = i160;
                }
                else if (UInt256.TryParse(s, out UInt256 i256))
                {
                    parameter.Type  = ContractParameterType.Hash256;
                    parameter.Value = i256;
                }
                else if (BigInteger.TryParse(s.Substring(2), NumberStyles.AllowHexSpecifier, null, out BigInteger bi))
                {
                    parameter.Type  = ContractParameterType.Integer;
                    parameter.Value = bi;
                }
                else
                {
                    parameter.Type  = ContractParameterType.String;
                    parameter.Value = s;
                }
            }
            else if (ECPoint.TryParse(s, ECCurve.Secp256r1, out ECPoint point))
            {
                parameter.Type  = ContractParameterType.PublicKey;
                parameter.Value = point;
            }
            else
            {
                try
                {
                    parameter.Value = s.HexToBytes();
                    parameter.Type  = ContractParameterType.ByteArray;
                }
                catch (FormatException)
                {
                    parameter.Type  = ContractParameterType.String;
                    parameter.Value = s;
                }
            }
            parameters.Add(parameter);
            listView1.Items.Add(new ListViewItem(new[]
            {
                new ListViewItem.ListViewSubItem
                {
                    Name = "index",
                    Text = $"[{listView1.Items.Count}]"
                },
                new ListViewItem.ListViewSubItem
                {
                    Name = "type",
                    Text = parameter.Type.ToString()
                },
                new ListViewItem.ListViewSubItem
                {
                    Name = "value",
                    Text = GetValueString(parameter.Value)
                }
            }, -1)
            {
                Tag = parameter
            });
        }
コード例 #45
0
 public bool ContainsTransaction(UInt256 txHash)
 {
     return(this.unspentTransactions.ContainsKey(txHash));
 }
コード例 #46
0
        public bool ContainsBlock(UInt256 blockHash)
        {
            Slice value;

            return(db.TryGet(ReadOptions.Default, MakeExistsKey(blockHash), out value));
        }
コード例 #47
0
 void ISerializable.Deserialize(BinaryReader reader)
 {
     HashStart = reader.ReadSerializableArray <UInt256>(16);
     HashStop  = reader.ReadSerializable <UInt256>();
 }
コード例 #48
0
 public void SetUInt256(string key, UInt256 value) => AddOrReplace(key, value);
コード例 #49
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedIndices.Count == 0)
            {
                return;
            }
            ContractParameter parameter = (ContractParameter)listView1.SelectedItems[0].Tag;

            switch (parameter.Type)
            {
            case ContractParameterType.Signature:
                try
                {
                    byte[] signature = textBox2.Text.HexToBytes();
                    if (signature.Length != 64)
                    {
                        return;
                    }
                    parameter.Value = signature;
                }
                catch (FormatException)
                {
                    return;
                }
                break;

            case ContractParameterType.Boolean:
                parameter.Value = string.Equals(textBox2.Text, bool.TrueString, StringComparison.OrdinalIgnoreCase);
                break;

            case ContractParameterType.Integer:
                parameter.Value = BigInteger.Parse(textBox2.Text);
                break;

            case ContractParameterType.Hash160:
            {
                UInt160 hash;
                if (!UInt160.TryParse(textBox2.Text, out hash))
                {
                    return;
                }
                parameter.Value = hash;
            }
            break;

            case ContractParameterType.Hash256:
            {
                UInt256 hash;
                if (!UInt256.TryParse(textBox2.Text, out hash))
                {
                    return;
                }
                parameter.Value = hash;
            }
            break;

            case ContractParameterType.ByteArray:
                try
                {
                    parameter.Value = textBox2.Text.HexToBytes();
                }
                catch (FormatException)
                {
                    return;
                }
                break;

            case ContractParameterType.PublicKey:
                try
                {
                    parameter.Value = ECPoint.Parse(textBox2.Text, ECCurve.Secp256r1);
                }
                catch (FormatException)
                {
                    return;
                }
                break;

            case ContractParameterType.String:
                parameter.Value = textBox2.Text;
                break;
            }
            listView1.SelectedItems[0].SubItems["value"].Text = GetValueString(parameter.Value);
            textBox1.Text = listView1.SelectedItems[0].SubItems["value"].Text;
            textBox2.Clear();
        }
コード例 #50
0
ファイル: Wallet.cs プロジェクト: NewEconoLab/NEL.LightDB
 public virtual Coin[] FindUnspentCoins(UInt256 asset_id, Fixed8 amount, params UInt160[] from)
 {
     return(FindUnspentCoins(FindUnspentCoins(from), asset_id, amount));
 }
コード例 #51
0
        public StateRootState GetStateRoot(UInt256 block_hash)
        {
            var block = GetBlock(block_hash);

            return(block is null ? null : GetStateRoot(block.Index));
        }
コード例 #52
0
ファイル: Wallet.cs プロジェクト: NewEconoLab/NEL.LightDB
 public Fixed8 GetBalance(UInt256 asset_id)
 {
     return(GetCoins(GetAccounts().Select(p => p.ScriptHash)).Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id)).Sum(p => p.Output.Value));
 }
コード例 #53
0
        public void DoWork()
        {
            #region Checking Fields
            Global.AssetDescriptor asset = Asset as Global.AssetDescriptor;
            string fromAddress           = FromAddr;
            string toAddress             = ToAddr;
            string strAmount             = Amount;
            string strFee = Fee;
            byte   toAddrVersion;
            byte   fromAddrVersion;

            if (asset == null)
            {
                throw new InvalidOperationException("Anchor is not correct");
            }

            if (!Fixed8.TryParse(strAmount, out Fixed8 amount))
            {
                throw new InvalidOperationException("Anchor is not correct");
            }
            if (amount == Fixed8.Zero)
            {
                throw new InvalidOperationException("Anchor is not correct");
            }
            if (amount.GetData() % (long)Math.Pow(10, 8 - (Asset as Global.AssetDescriptor).Precision) != 0)
            {
                throw new InvalidOperationException("Anchor is not correct");
            }

            if (!Fixed8.TryParse(strFee, out Fixed8 fee))
            {
                throw new InvalidOperationException("Anchor is not correct");
            }
            if (fee < Fixed8.Zero)
            {
                throw new InvalidOperationException("Anchor is not correct");
            }

            try
            {
                fromAddrVersion = Wallet.GetAddressVersion(fromAddress);
                toAddrVersion   = Wallet.GetAddressVersion(toAddress);
            }
            catch
            {
                throw new InvalidOperationException("Anchor is not correct");
            }

            Transaction tx;
            #endregion
            #region T -> T
            if (toAddrVersion == Wallet.AddressVersion && fromAddrVersion == Wallet.AddressVersion) // T -> T
            {
                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new ContractTransaction();

                //if (!string.IsNullOrEmpty(remark))
                //    attributes.Add(new TransactionAttribute
                //    {
                //        Usage = TransactionAttributeUsage.Remark,
                //        Data = Encoding.UTF8.GetBytes(remark)
                //    });

                tx.Attributes = attributes.ToArray();
                TransactionOutput outPut = new TransactionOutput();
                outPut.ScriptHash = Wallet.ToScriptHash(toAddress);
                outPut.Value      = amount;
                outPut.AssetId    = (UInt256)asset.AssetId;
                outPut.Fee        = fee;
                tx.Outputs        = new TransactionOutput[1];
                tx.Outputs[0]     = outPut;
                if (tx is ContractTransaction ctx)
                {
                    tx = Constant.CurrentWallet.MakeTransactionFrom(ctx, fromAddress);
                    if (tx == null)
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }

                /*
                 * if (tx is InvocationTransaction itx)
                 * {
                 *  using (InvokeContractDialog dialog = new InvokeContractDialog(itx))
                 *  {
                 *      if (dialog.ShowDialog() != DialogResult.OK) return;
                 *      tx = dialog.GetTransaction();
                 *  }
                 * }
                 */
                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region T -> A
            else if (fromAddrVersion == Wallet.AddressVersion && toAddrVersion == Wallet.AnonymouseAddressVersion)  // T -> A
            {
                UInt256 joinSplitPubKey_;
                byte[]  joinSplitPrivKey_;

                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new AnonymousContractTransaction();

                tx.Attributes = attributes.ToArray();

                Sodium.KeyPair keyPair;
                keyPair = Sodium.PublicKeyAuth.GenerateKeyPair();

                joinSplitPubKey_  = new UInt256(keyPair.PublicKey);
                joinSplitPrivKey_ = keyPair.PrivateKey;

                ((AnonymousContractTransaction)tx).joinSplitPubKey = joinSplitPubKey_;

                AsyncJoinSplitInfo info = new AsyncJoinSplitInfo();
                info.vpub_old = new Fixed8(0);
                info.vpub_new = new Fixed8(0);

                JSOutput jsOut = new JSOutput(Wallet.ToPaymentAddress(toAddress), amount, (UInt256)asset.AssetId);

                info.vjsout.Add(jsOut);
                info.vpub_old += amount;

                if (tx is AnonymousContractTransaction ctx)
                {
                    tx = Constant.CurrentWallet.MakeTandATransaction(ctx, fromAddress, info);
                    if (tx is AnonymousContractTransaction ctx_)
                    {
                        IntPtr w = SnarkDllApi.Witnesses_Create();

                        IntPtr ptrRoot = SnarkDllApi.GetCMRoot(Blockchain.Default.GetCmMerkleTree());

                        byte[] byRoot = new byte[32];
                        System.Runtime.InteropServices.Marshal.Copy(ptrRoot, byRoot, 0, 32);
                        UInt256 anchor = new UInt256(byRoot);

                        tx = Constant.CurrentWallet.Perform_JoinSplit(ctx_, info, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)asset.AssetId, w, anchor);

                        /*
                         * int dstOffset = 0;
                         * byte[] byJsBody = new byte[ctx_.byJoinSplit.GetListLength()];
                         * for (int index = 0; index < ctx_.byJoinSplit.Count; index++)
                         * {
                         *  Buffer.BlockCopy(ctx_.byJoinSplit[index], 0, byJsBody, dstOffset, ctx_.byJoinSplit[index].Length);
                         *  dstOffset += ctx_.byJoinSplit[index].Length;
                         * }
                         *
                         * UInt256 jsHash = new UInt256(Crypto.Default.Hash256(byJsBody));
                         */

                        ctx_.joinSplitSig = Sodium.PublicKeyAuth.SignDetached(ctx.JsHash.ToArray(), joinSplitPrivKey_);

                        if (!Sodium.PublicKeyAuth.VerifyDetached(ctx_.joinSplitSig, ctx.JsHash.ToArray(), joinSplitPubKey_.ToArray()))
                        {
                            throw new InvalidOperationException("Anchor is not correct");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }
                else
                {
                    throw new InvalidOperationException("Anchor is not correct");
                }

                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region A -> T
            else if (fromAddrVersion == Wallet.AnonymouseAddressVersion && toAddrVersion == Wallet.AddressVersion)  // A -> T
            {
                UInt256 joinSplitPubKey_;
                byte[]  joinSplitPrivKey_;

                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new AnonymousContractTransaction();

                Fixed8 vpubNewTarget = Fixed8.Zero;
                Fixed8 totalAmount   = amount;

                tx.Attributes = attributes.ToArray();

                Sodium.KeyPair keyPair;
                keyPair = Sodium.PublicKeyAuth.GenerateKeyPair();

                joinSplitPubKey_  = new UInt256(keyPair.PublicKey);
                joinSplitPrivKey_ = keyPair.PrivateKey;

                ((AnonymousContractTransaction)tx).joinSplitPubKey = joinSplitPubKey_;

                // Do process the transparent outputs.
                TransactionOutput outPut = new TransactionOutput();
                outPut.ScriptHash = Wallet.ToScriptHash(toAddress);
                outPut.Value      = amount;
                outPut.AssetId    = (UInt256)asset.AssetId;
                tx.Outputs        = new TransactionOutput[1];
                tx.Outputs[0]     = outPut;

                tx.Scripts = new Witness[0];

                vpubNewTarget = amount;

                AsyncJoinSplitInfo info = new AsyncJoinSplitInfo();
                info.vpub_old = Fixed8.Zero;
                info.vpub_new = Fixed8.Zero;

                Fixed8 jsInputValue = Fixed8.Zero;


                IntPtr ptrRoot = SnarkDllApi.GetCMRoot(Blockchain.Default.GetCmMerkleTree());

                byte[] byRoot = new byte[32];
                System.Runtime.InteropServices.Marshal.Copy(ptrRoot, byRoot, 0, 32);
                UInt256 jsAnchor = new UInt256(byRoot);

                if (tx is AnonymousContractTransaction ctx)
                {
                    tx = Constant.CurrentWallet.MakeAandTTransaction(ctx, fromAddress, info);

                    #region Split token types
                    /* ******************************   Split the info into main token and fee token  ********************************** */
                    AsyncJoinSplitInfo mainTokenInfo            = new AsyncJoinSplitInfo();
                    AsyncJoinSplitInfo subTokenInfo             = new AsyncJoinSplitInfo();
                    Fixed8             main_total_output_amount = Fixed8.Zero;
                    Fixed8             sub_total_output_amount  = Fixed8.Zero;

                    for (int i = 0; i < info.vjsin.Count; i++)
                    {
                        if (info.vjsin[i].AssetID == Blockchain.UtilityToken.Hash)
                        {
                            subTokenInfo.vjsin.Add(info.vjsin[i]);
                            subTokenInfo.notes.Add(info.vjsin[i].note);
                        }
                        else
                        {
                            mainTokenInfo.vjsin.Add(info.vjsin[i]);
                            mainTokenInfo.notes.Add(info.vjsin[i].note);
                        }
                    }

                    for (int i = 0; i < info.vjsout.Count; i++)
                    {
                        if (info.vjsout[i].AssetID == Blockchain.UtilityToken.Hash)
                        {
                            subTokenInfo.vjsout.Add(info.vjsout[i]);
                            sub_total_output_amount += info.vjsout[i].value;
                        }
                        else
                        {
                            mainTokenInfo.vjsout.Add(info.vjsout[i]);
                            main_total_output_amount += info.vjsout[i].value;
                        }
                    }
                    /* ******************************                      End                        ********************************** */
                    #endregion

                    IntPtr vectorWitness = SnarkDllApi.Witnesses_Create();

                    int    jsIndex = 0;
                    Fixed8 current_inputed_amount = Fixed8.Zero;
                    Fixed8 rest_amount            = totalAmount;

                    #region Do Process the Main token part
                    for (int i = 0; i < mainTokenInfo.vjsin.Count; i++)
                    {
                        IntPtr witness = SnarkDllApi.CmWitness_Create();

                        SnarkDllApi.SetCMWitnessFromBinary(witness, mainTokenInfo.vjsin[i].witness, mainTokenInfo.vjsin[i].witness.Length);
                        SnarkDllApi.Witnesses_Add(vectorWitness, witness);

                        IntPtr ptrWitness = SnarkDllApi.GetCMRootFromWitness(witness);
                        byte[] byWRoot    = new byte[32];
                        System.Runtime.InteropServices.Marshal.Copy(ptrWitness, byWRoot, 0, 32);
                        UInt256 wAnchor = new UInt256(byWRoot);

                        if (jsAnchor != wAnchor)
                        {
                            throw new InvalidOperationException("Anchor is not correct");
                        }

                        current_inputed_amount += mainTokenInfo.vjsin[i].note.value;

                        jsIndex++;

                        if (jsIndex == 2 && i != mainTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();
                            jsInfo.vjsin.Add(mainTokenInfo.vjsin[i - 1]);
                            jsInfo.vjsin.Add(mainTokenInfo.vjsin[i]);

                            jsInfo.notes.Add(mainTokenInfo.notes[i - 1]);
                            jsInfo.notes.Add(mainTokenInfo.notes[i]);

                            var vInputsSum = jsInfo.vjsin[0].note.value + jsInfo.vjsin[1].note.value;

                            for (int oti = 0; oti < mainTokenInfo.vjsout.Count; oti++)
                            {
                                if (mainTokenInfo.vjsout[oti].value >= vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, vInputsSum, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    mainTokenInfo.vjsout[oti].value -= vInputsSum;

                                    vInputsSum = Fixed8.Zero;
                                    break;
                                }

                                if (mainTokenInfo.vjsout[oti].value < vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, mainTokenInfo.vjsout[oti].value, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    vInputsSum = vInputsSum - mainTokenInfo.vjsout[oti].value;
                                    mainTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (vInputsSum >= Fixed8.Zero)
                            {
                                jsInfo.vpub_new = vInputsSum;
                            }

                            tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }

                        if (i == mainTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();

                            Fixed8 jsInputedAmount = Fixed8.Zero;

                            for (int ji = jsIndex - 1; ji > -1; ji--)
                            {
                                jsInfo.vjsin.Add(mainTokenInfo.vjsin[i - ji]);
                                jsInfo.notes.Add(mainTokenInfo.notes[i - ji]);

                                jsInputedAmount += mainTokenInfo.notes[i - ji].value;
                                rest_amount     -= mainTokenInfo.notes[i - ji].value;
                            }

                            for (int oti = 0; oti < mainTokenInfo.vjsout.Count; oti++)
                            {
                                if (mainTokenInfo.vjsout[oti].value >= jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, jsInputedAmount, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    mainTokenInfo.vjsout[oti].value -= jsInputedAmount;

                                    jsInputedAmount = Fixed8.Zero;
                                    break;
                                }

                                if (mainTokenInfo.vjsout[oti].value < jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, mainTokenInfo.vjsout[oti].value, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    jsInputedAmount = jsInputedAmount - mainTokenInfo.vjsout[oti].value;
                                    mainTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (jsInputedAmount != Fixed8.Zero)
                            {
                                jsInfo.vpub_new = jsInputedAmount;
                            }

                            try
                            {
                                tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);
                            }
                            catch (Exception ex)
                            {
                                string strException = ex.Message;
                                throw new InvalidOperationException("JoinSplit Errors");
                            }

                            if (tx.Inputs == null)
                            {
                                tx.Inputs = new CoinReference[0];
                            }

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }
                    }
                    #endregion
                    #region Do Process the Fee token part, And when sending the QRG token, then there is no Main token part.
                    for (int i = 0; i < subTokenInfo.vjsin.Count; i++)
                    {
                        IntPtr witness = SnarkDllApi.CmWitness_Create();

                        SnarkDllApi.SetCMWitnessFromBinary(witness, subTokenInfo.vjsin[i].witness, subTokenInfo.vjsin[i].witness.Length);
                        SnarkDllApi.Witnesses_Add(vectorWitness, witness);

                        IntPtr ptrWitness = SnarkDllApi.GetCMRootFromWitness(witness);
                        byte[] byWRoot    = new byte[32];
                        System.Runtime.InteropServices.Marshal.Copy(ptrWitness, byWRoot, 0, 32);
                        UInt256 wAnchor = new UInt256(byWRoot);

                        if (jsAnchor != wAnchor)
                        {
                            throw new InvalidOperationException("Anchor is not correct");
                        }

                        current_inputed_amount += subTokenInfo.vjsin[i].note.value;

                        jsIndex++;

                        if (jsIndex == 2 && i != subTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();
                            jsInfo.vjsin.Add(subTokenInfo.vjsin[i - 1]);
                            jsInfo.vjsin.Add(subTokenInfo.vjsin[i]);

                            jsInfo.notes.Add(subTokenInfo.notes[i - 1]);
                            jsInfo.notes.Add(subTokenInfo.notes[i]);

                            var vInputsSum = jsInfo.vjsin[0].note.value + jsInfo.vjsin[1].note.value;

                            for (int oti = 0; oti < subTokenInfo.vjsout.Count; oti++)
                            {
                                if (subTokenInfo.vjsout[oti].value >= vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, vInputsSum, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    subTokenInfo.vjsout[oti].value -= vInputsSum;

                                    vInputsSum = Fixed8.Zero;
                                    break;
                                }

                                if (subTokenInfo.vjsout[oti].value < vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, subTokenInfo.vjsout[oti].value, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    vInputsSum = vInputsSum - subTokenInfo.vjsout[oti].value;
                                    subTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (vInputsSum >= Fixed8.Zero)
                            {
                                jsInfo.vpub_new = vInputsSum;
                            }

                            tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }

                        if (i == subTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();

                            Fixed8 jsInputedAmount = Fixed8.Zero;

                            for (int ji = jsIndex - 1; ji > -1; ji--)
                            {
                                jsInfo.vjsin.Add(subTokenInfo.vjsin[i - ji]);
                                jsInfo.notes.Add(subTokenInfo.notes[i - ji]);

                                jsInputedAmount += subTokenInfo.notes[i - ji].value;
                                rest_amount     -= subTokenInfo.notes[i - ji].value;
                            }

                            for (int oti = 0; oti < subTokenInfo.vjsout.Count; oti++)
                            {
                                if (subTokenInfo.vjsout[oti].value >= jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, jsInputedAmount, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    subTokenInfo.vjsout[oti].value -= jsInputedAmount;

                                    jsInputedAmount = Fixed8.Zero;
                                    break;
                                }

                                if (subTokenInfo.vjsout[oti].value < jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, subTokenInfo.vjsout[oti].value, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    jsInputedAmount = jsInputedAmount - subTokenInfo.vjsout[oti].value;
                                    subTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (jsInputedAmount != Fixed8.Zero)
                            {
                                jsInfo.vpub_new = jsInputedAmount;
                            }

                            try
                            {
                                tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);
                            }
                            catch (Exception ex)
                            {
                                string strException = ex.Message;
                                throw new InvalidOperationException("JoinSplit Errors");
                            }

                            if (tx.Inputs == null)
                            {
                                tx.Inputs = new CoinReference[0];
                            }

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }
                    }
                    #endregion

                    /*
                     * int dstOffset = 0;
                     * byte[] byJsBody = new byte[ctx.byJoinSplit.GetListLength()];
                     * for (int index = 0; index < ctx.byJoinSplit.Count; index++)
                     * {
                     *  Buffer.BlockCopy(ctx.byJoinSplit[index], 0, byJsBody, dstOffset, ctx.byJoinSplit[index].Length);
                     *  dstOffset += ctx.byJoinSplit[index].Length;
                     * }
                     *
                     * UInt256 jsHash = new UInt256(Crypto.Default.Hash256(byJsBody));
                     */

                    //UInt256 tmp_jsHash = ctx.JsHash;

                    ctx.joinSplitSig = Sodium.PublicKeyAuth.SignDetached(ctx.JsHash.ToArray(), joinSplitPrivKey_);

                    if (!Sodium.PublicKeyAuth.VerifyDetached(ctx.joinSplitSig, ctx.JsHash.ToArray(), joinSplitPubKey_.ToArray()))
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }
                else
                {
                    throw new InvalidOperationException("Anchor is not correct");
                }
                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region A -> A
            else if (fromAddrVersion == Wallet.AnonymouseAddressVersion && toAddrVersion == Wallet.AnonymouseAddressVersion)    // A -> A
            {
                UInt256 joinSplitPubKey_;
                byte[]  joinSplitPrivKey_;

                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new AnonymousContractTransaction();

                Fixed8 totalAmount = amount;

                tx.Scripts = new Witness[0];

                tx.Attributes = attributes.ToArray();

                Sodium.KeyPair keyPair;
                keyPair = Sodium.PublicKeyAuth.GenerateKeyPair();

                joinSplitPubKey_  = new UInt256(keyPair.PublicKey);
                joinSplitPrivKey_ = keyPair.PrivateKey;

                ((AnonymousContractTransaction)tx).joinSplitPubKey = joinSplitPubKey_;

                AsyncJoinSplitInfo info = new AsyncJoinSplitInfo();
                info.vpub_old = Fixed8.Zero;
                info.vpub_new = Fixed8.Zero;

                JSOutput jsOut = new JSOutput(Wallet.ToPaymentAddress(toAddress), amount, (UInt256)asset.AssetId);

                info.vjsout.Add(jsOut);

                Fixed8 jsInputValue = Fixed8.Zero;


                IntPtr ptrRoot = SnarkDllApi.GetCMRoot(Blockchain.Default.GetCmMerkleTree());

                byte[] byRoot = new byte[32];
                System.Runtime.InteropServices.Marshal.Copy(ptrRoot, byRoot, 0, 32);
                UInt256 jsAnchor = new UInt256(byRoot);

                if (tx is AnonymousContractTransaction ctx)
                {
                    tx = Constant.CurrentWallet.MakeAandATransaction(ctx, fromAddress, info);
                    #region Split token type
                    /* ******************************   Split the info into main token and fee token  ********************************** */
                    AsyncJoinSplitInfo mainTokenInfo            = new AsyncJoinSplitInfo();
                    AsyncJoinSplitInfo subTokenInfo             = new AsyncJoinSplitInfo();
                    Fixed8             main_total_output_amount = Fixed8.Zero;
                    Fixed8             sub_total_output_amount  = Fixed8.Zero;

                    for (int i = 0; i < info.vjsin.Count; i++)
                    {
                        if (info.vjsin[i].AssetID == Blockchain.UtilityToken.Hash)
                        {
                            subTokenInfo.vjsin.Add(info.vjsin[i]);
                            subTokenInfo.notes.Add(info.vjsin[i].note);
                        }
                        else
                        {
                            mainTokenInfo.vjsin.Add(info.vjsin[i]);
                            mainTokenInfo.notes.Add(info.vjsin[i].note);
                        }
                    }

                    for (int i = 0; i < info.vjsout.Count; i++)
                    {
                        if (info.vjsout[i].AssetID == Blockchain.UtilityToken.Hash)
                        {
                            subTokenInfo.vjsout.Add(info.vjsout[i]);
                            sub_total_output_amount += info.vjsout[i].value;
                        }
                        else
                        {
                            mainTokenInfo.vjsout.Add(info.vjsout[i]);
                            main_total_output_amount += info.vjsout[i].value;
                        }
                    }
                    /* ******************************                      End                        ********************************** */
                    #endregion
                    IntPtr vectorWitness = SnarkDllApi.Witnesses_Create();

                    int    jsIndex = 0;
                    Fixed8 current_inputed_amount = Fixed8.Zero;
                    Fixed8 rest_amount            = totalAmount;

                    #region Do Process the Main token part
                    for (int i = 0; i < mainTokenInfo.vjsin.Count; i++)
                    {
                        IntPtr witness = SnarkDllApi.CmWitness_Create();

                        SnarkDllApi.SetCMWitnessFromBinary(witness, mainTokenInfo.vjsin[i].witness, mainTokenInfo.vjsin[i].witness.Length);
                        SnarkDllApi.Witnesses_Add(vectorWitness, witness);

                        IntPtr ptrWitness = SnarkDllApi.GetCMRootFromWitness(witness);
                        byte[] byWRoot    = new byte[32];
                        System.Runtime.InteropServices.Marshal.Copy(ptrWitness, byWRoot, 0, 32);
                        UInt256 wAnchor = new UInt256(byWRoot);

                        if (jsAnchor != wAnchor)
                        {
                            throw new InvalidOperationException("Anchor is not correct");
                        }

                        current_inputed_amount += mainTokenInfo.vjsin[i].note.value;

                        jsIndex++;

                        if (jsIndex == 2 && i != mainTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();
                            jsInfo.vjsin.Add(mainTokenInfo.vjsin[i - 1]);
                            jsInfo.vjsin.Add(mainTokenInfo.vjsin[i]);

                            jsInfo.notes.Add(mainTokenInfo.notes[i - 1]);
                            jsInfo.notes.Add(mainTokenInfo.notes[i]);

                            var vInputsSum = jsInfo.vjsin[0].note.value + jsInfo.vjsin[1].note.value;

                            for (int oti = 0; oti < mainTokenInfo.vjsout.Count; oti++)
                            {
                                if (mainTokenInfo.vjsout[oti].value >= vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, vInputsSum, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    mainTokenInfo.vjsout[oti].value -= vInputsSum;

                                    vInputsSum = Fixed8.Zero;
                                    break;
                                }

                                if (mainTokenInfo.vjsout[oti].value < vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, mainTokenInfo.vjsout[oti].value, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    vInputsSum = vInputsSum - mainTokenInfo.vjsout[oti].value;
                                    mainTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }

                        if (i == mainTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();

                            Fixed8 jsInputedAmount = Fixed8.Zero;

                            for (int ji = jsIndex - 1; ji > -1; ji--)
                            {
                                jsInfo.vjsin.Add(mainTokenInfo.vjsin[i - ji]);
                                jsInfo.notes.Add(mainTokenInfo.notes[i - ji]);

                                jsInputedAmount += mainTokenInfo.notes[i - ji].value;
                                rest_amount     -= mainTokenInfo.notes[i - ji].value;
                            }

                            for (int oti = 0; oti < mainTokenInfo.vjsout.Count; oti++)
                            {
                                if (mainTokenInfo.vjsout[oti].value >= jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, jsInputedAmount, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    mainTokenInfo.vjsout[oti].value -= jsInputedAmount;

                                    jsInputedAmount = Fixed8.Zero;
                                    break;
                                }

                                if (mainTokenInfo.vjsout[oti].value < jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(mainTokenInfo.vjsout[oti].addr, mainTokenInfo.vjsout[oti].value, mainTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    jsInputedAmount = jsInputedAmount - mainTokenInfo.vjsout[oti].value;
                                    mainTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (jsInputedAmount != Fixed8.Zero)
                            {
                                jsInfo.vpub_new = jsInputedAmount;
                            }

                            try
                            {
                                tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);
                            }
                            catch (Exception ex)
                            {
                                string strException = ex.Message;
                                throw new InvalidOperationException("JoinSplit Errors");
                            }

                            if (tx.Inputs == null)
                            {
                                tx.Inputs = new CoinReference[0];
                            }

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }
                    }
                    #endregion
                    #region Do Process the Fee token part, And when sending the QRG token, then there is no Main token part.
                    for (int i = 0; i < subTokenInfo.vjsin.Count; i++)
                    {
                        IntPtr witness = SnarkDllApi.CmWitness_Create();

                        SnarkDllApi.SetCMWitnessFromBinary(witness, subTokenInfo.vjsin[i].witness, subTokenInfo.vjsin[i].witness.Length);
                        SnarkDllApi.Witnesses_Add(vectorWitness, witness);

                        IntPtr ptrWitness = SnarkDllApi.GetCMRootFromWitness(witness);
                        byte[] byWRoot    = new byte[32];
                        System.Runtime.InteropServices.Marshal.Copy(ptrWitness, byWRoot, 0, 32);
                        UInt256 wAnchor = new UInt256(byWRoot);

                        if (jsAnchor != wAnchor)
                        {
                            throw new InvalidOperationException("Anchor is not correct");
                        }

                        current_inputed_amount += subTokenInfo.vjsin[i].note.value;

                        jsIndex++;

                        if (jsIndex == 2 && i != subTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();
                            jsInfo.vjsin.Add(subTokenInfo.vjsin[i - 1]);
                            jsInfo.vjsin.Add(subTokenInfo.vjsin[i]);

                            jsInfo.notes.Add(subTokenInfo.notes[i - 1]);
                            jsInfo.notes.Add(subTokenInfo.notes[i]);

                            var vInputsSum = jsInfo.vjsin[0].note.value + jsInfo.vjsin[1].note.value;

                            for (int oti = 0; oti < subTokenInfo.vjsout.Count; oti++)
                            {
                                if (subTokenInfo.vjsout[oti].value >= vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, vInputsSum, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    subTokenInfo.vjsout[oti].value -= vInputsSum;

                                    vInputsSum = Fixed8.Zero;
                                    break;
                                }

                                if (subTokenInfo.vjsout[oti].value < vInputsSum)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, subTokenInfo.vjsout[oti].value, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    vInputsSum = vInputsSum - subTokenInfo.vjsout[oti].value;
                                    subTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }

                        if (i == subTokenInfo.vjsin.Count - 1)
                        {
                            AsyncJoinSplitInfo jsInfo = new AsyncJoinSplitInfo();

                            Fixed8 jsInputedAmount = Fixed8.Zero;

                            for (int ji = jsIndex - 1; ji > -1; ji--)
                            {
                                jsInfo.vjsin.Add(subTokenInfo.vjsin[i - ji]);
                                jsInfo.notes.Add(subTokenInfo.notes[i - ji]);

                                jsInputedAmount += subTokenInfo.notes[i - ji].value;
                                rest_amount     -= subTokenInfo.notes[i - ji].value;
                            }

                            for (int oti = 0; oti < subTokenInfo.vjsout.Count; oti++)
                            {
                                if (subTokenInfo.vjsout[oti].value >= jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, jsInputedAmount, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);
                                    subTokenInfo.vjsout[oti].value -= jsInputedAmount;

                                    jsInputedAmount = Fixed8.Zero;
                                    break;
                                }

                                if (subTokenInfo.vjsout[oti].value < jsInputedAmount)
                                {
                                    JSOutput jsOut1 = new JSOutput(subTokenInfo.vjsout[oti].addr, subTokenInfo.vjsout[oti].value, subTokenInfo.vjsout[oti].AssetID);
                                    jsInfo.vjsout.Add(jsOut1);

                                    jsInputedAmount = jsInputedAmount - subTokenInfo.vjsout[oti].value;
                                    subTokenInfo.vjsout[oti].value = Fixed8.Zero;
                                }
                            }

                            if (jsInputedAmount != Fixed8.Zero)
                            {
                                jsInfo.vpub_new = jsInputedAmount;
                            }

                            try
                            {
                                tx = Constant.CurrentWallet.Perform_JoinSplit(ctx, jsInfo, joinSplitPubKey_, joinSplitPrivKey_, (UInt256)jsInfo.vjsin[0].AssetID, vectorWitness, jsAnchor);
                            }
                            catch (Exception ex)
                            {
                                string strException = ex.Message;
                                throw new InvalidOperationException("JoinSplit Errors");
                            }

                            if (tx.Inputs == null)
                            {
                                tx.Inputs = new CoinReference[0];
                            }

                            jsIndex = 0;
                            SnarkDllApi.Witnesses_Clear(vectorWitness);
                        }
                    }
                    #endregion



                    /*
                     * int dstOffset = 0;
                     * byte[] byJsBody = new byte[ctx.byJoinSplit.GetListLength()];
                     * for (int index = 0; index < ctx.byJoinSplit.Count; index++)
                     * {
                     *  Buffer.BlockCopy(ctx.byJoinSplit[index], 0, byJsBody, dstOffset, ctx.byJoinSplit[index].Length);
                     *  dstOffset += ctx.byJoinSplit[index].Length;
                     * }
                     *
                     * UInt256 jsHash = new UInt256(Crypto.Default.Hash256(byJsBody));
                     */

                    ctx.joinSplitSig = Sodium.PublicKeyAuth.SignDetached(ctx.JsHash.ToArray(), joinSplitPrivKey_);

                    if (!Sodium.PublicKeyAuth.VerifyDetached(ctx.joinSplitSig, ctx.JsHash.ToArray(), joinSplitPubKey_.ToArray()))
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }
                else
                {
                    throw new InvalidOperationException("Anchor is not correct");
                }
                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region S -> S
            else if (fromAddrVersion == Wallet.StealthAddressVersion && toAddrVersion == Wallet.StealthAddressVersion)
            {
                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new RingConfidentialTransaction();

                tx.Attributes = attributes.ToArray();

                if (tx is RingConfidentialTransaction ctx)
                {
                    List <RCTransactionOutput>             rctOutput   = new List <RCTransactionOutput>();
                    Pure.Wallets.StealthKey.StealthKeyPair fromKeyPair = null;
                    foreach (KeyPairBase key in Constant.CurrentWallet.GetKeys())
                    {
                        if (key is Pure.Wallets.StealthKey.StealthKeyPair rctKey)
                        {
                            if (Wallet.ToStealthAddress(rctKey) == fromAddress)
                            {
                                fromKeyPair = rctKey;
                            }
                        }
                    }

                    if (fromKeyPair == null)
                    {
                        throw new InvalidOperationException("From key is not exist.");
                    }

                    byte[] r = SchnorrNonLinkable.GenerateRandomScalar();
                    Pure.Cryptography.ECC.ECPoint R = Pure.Cryptography.ECC.ECCurve.Secp256r1.G * r;

                    Pure.Wallets.StealthKey.StealthPubKeys outPubKey = Wallet.ToStealthKeyPair(toAddress).ToStelathPubKeys();

                    RCTransactionOutput output = new RCTransactionOutput
                    {
                        AssetId    = (UInt256)asset.AssetId,
                        PubKey     = Pure.Cryptography.ECC.ECPoint.DecodePoint(outPubKey.GenPaymentPubKeyHash(r), Pure.Cryptography.ECC.ECCurve.Secp256r1),
                        Value      = amount,
                        ScriptHash = Pure.SmartContract.Contract.CreateRingSignatureRedeemScript(outPubKey.PayloadPubKey, outPubKey.ViewPubKey).ToScriptHash()
                    };

                    rctOutput.Add(output);
                    ctx.Scripts = new Witness[0];

                    tx = Constant.CurrentWallet.MakeRCTransaction(ctx, fromAddress, rctOutput, fromKeyPair, r);

                    if (tx == null)
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }

                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region T -> S
            else if (fromAddrVersion == Wallet.AddressVersion && toAddrVersion == Wallet.StealthAddressVersion)
            {
                tx = new RingConfidentialTransaction();

                List <TransactionAttribute> attributes = new List <TransactionAttribute>();
                tx.Attributes = attributes.ToArray();

                if (tx is RingConfidentialTransaction rtx)
                {
                    List <RCTransactionOutput> rctOutput = new List <RCTransactionOutput>();

                    byte[] r = SchnorrNonLinkable.GenerateRandomScalar();
                    Pure.Cryptography.ECC.ECPoint R = Pure.Cryptography.ECC.ECCurve.Secp256r1.G * r;

                    Pure.Wallets.StealthKey.StealthPubKeys outPubKey = Wallet.ToStealthKeyPair(toAddress).ToStelathPubKeys();

                    RCTransactionOutput output = new RCTransactionOutput
                    {
                        AssetId    = (UInt256)asset.AssetId,
                        PubKey     = Pure.Cryptography.ECC.ECPoint.DecodePoint(outPubKey.GenPaymentPubKeyHash(r), Pure.Cryptography.ECC.ECCurve.Secp256r1),
                        Value      = amount,
                        ScriptHash = Pure.SmartContract.Contract.CreateRingSignatureRedeemScript(outPubKey.PayloadPubKey, outPubKey.ViewPubKey).ToScriptHash()
                    };

                    rctOutput.Add(output);

                    tx = Constant.CurrentWallet.MakeRCTransaction(rtx, fromAddress, rctOutput, null, r);

                    if (tx == null)
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }

                Helper.SignAndShowInformation(tx);
            }
            #endregion
            #region S -> T
            else if (fromAddrVersion == Wallet.StealthAddressVersion && toAddrVersion == Wallet.AddressVersion)
            {
                List <TransactionAttribute> attributes = new List <TransactionAttribute>();

                tx = new RingConfidentialTransaction();

                tx.Attributes = attributes.ToArray();

                if (tx is RingConfidentialTransaction ctx)
                {
                    List <RCTransactionOutput>             rctOutput   = new List <RCTransactionOutput>();
                    Pure.Wallets.StealthKey.StealthKeyPair fromKeyPair = null;
                    foreach (KeyPairBase key in Constant.CurrentWallet.GetKeys())
                    {
                        if (key is Pure.Wallets.StealthKey.StealthKeyPair rctKey)
                        {
                            if (Wallet.ToStealthAddress(rctKey) == fromAddress)
                            {
                                fromKeyPair = rctKey;
                            }
                        }
                    }

                    if (fromKeyPair == null)
                    {
                        throw new InvalidOperationException("From key is not exist.");
                    }

                    byte[] r = SchnorrNonLinkable.GenerateRandomScalar();
                    Pure.Cryptography.ECC.ECPoint R = Pure.Cryptography.ECC.ECCurve.Secp256r1.G * r;

                    ctx.Scripts = new Witness[0];

                    TransactionOutput outPut = new TransactionOutput();
                    outPut.ScriptHash = Wallet.ToScriptHash(toAddress);
                    outPut.Value      = amount;
                    outPut.AssetId    = (UInt256)asset.AssetId;
                    tx.Outputs        = new TransactionOutput[1];
                    tx.Outputs[0]     = outPut;

                    tx = Constant.CurrentWallet.MakeRCTransaction(ctx, fromAddress, rctOutput, fromKeyPair, r);

                    if (tx == null)
                    {
                        throw new InvalidOperationException("Anchor is not correct");
                    }
                }

                Helper.SignAndShowInformation(tx);
            }
            #endregion
        }
コード例 #54
0
ファイル: Wallet.cs プロジェクト: NewEconoLab/NEL.LightDB
 public Fixed8 GetAvailable(UInt256 asset_id)
 {
     return(FindUnspentCoins().Where(p => p.Output.AssetId.Equals(asset_id)).Sum(p => p.Output.Value));
 }
コード例 #55
0
 private static void CheckMemoryAccessViolation(ref UInt256 location, in UInt256 length)
コード例 #56
0
        private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTracer, bool readOnly)
        {
            var notSystemTransaction = !transaction.IsSystem();
            IReleaseSpec spec = _specProvider.GetSpec(block.Number);
            if (!notSystemTransaction)
            {
                spec = new SystemTransactionReleaseSpec(spec);
            }
            
            Address recipient = transaction.To;
            UInt256 value = transaction.Value;
            UInt256 gasPrice = transaction.GasPrice;
            long gasLimit = (long) transaction.GasLimit;
            byte[] machineCode = transaction.Init;
            byte[] data = transaction.Data ?? Bytes.Empty;

            Address sender = transaction.SenderAddress;
            if (_logger.IsTrace) _logger.Trace($"Executing tx {transaction.Hash}");

            if (sender == null)
            {
                TraceLogInvalidTx(transaction, "SENDER_NOT_SPECIFIED");
                QuickFail(transaction, block, txTracer, readOnly);
                return;
            }

            long intrinsicGas = _intrinsicGasCalculator.Calculate(transaction, spec);
            if (_logger.IsTrace) _logger.Trace($"Intrinsic gas calculated for {transaction.Hash}: " + intrinsicGas);

            if (notSystemTransaction)
            {
                if (gasLimit < intrinsicGas)
                {
                    TraceLogInvalidTx(transaction, $"GAS_LIMIT_BELOW_INTRINSIC_GAS {gasLimit} < {intrinsicGas}");
                    QuickFail(transaction, block, txTracer, readOnly);
                    return;
                }

                if (gasLimit > block.GasLimit - block.GasUsed)
                {
                    TraceLogInvalidTx(transaction,
                        $"BLOCK_GAS_LIMIT_EXCEEDED {gasLimit} > {block.GasLimit} - {block.GasUsed}");
                    QuickFail(transaction, block, txTracer, readOnly);
                    return;
                }
            }

            if (!_stateProvider.AccountExists(sender))
            {
                // hacky fix for the potential recovery issue
                if (transaction.Signature != null)
                {
                    transaction.SenderAddress = _ecdsa.RecoverAddress(transaction, block.Number);
                }
                
                if (sender != transaction.SenderAddress)
                {
                    if(_logger.IsWarn) _logger.Warn($"TX recovery issue fixed - tx was coming with sender {sender} and the now it recovers to {transaction.SenderAddress}");
                    sender = transaction.SenderAddress;
                }
                else
                {
                    TraceLogInvalidTx(transaction, $"SENDER_ACCOUNT_DOES_NOT_EXIST {sender}");
                    if (gasPrice == UInt256.Zero)
                    {
                        _stateProvider.CreateAccount(sender, UInt256.Zero);
                    }                    
                }
            }

            if (notSystemTransaction)
            {
                UInt256 senderBalance = _stateProvider.GetBalance(sender);
                if ((ulong) intrinsicGas * gasPrice + value > senderBalance)
                {
                    TraceLogInvalidTx(transaction, $"INSUFFICIENT_SENDER_BALANCE: ({sender})_BALANCE = {senderBalance}");
                    QuickFail(transaction, block, txTracer, readOnly);
                    return;
                }

                if (transaction.Nonce != _stateProvider.GetNonce(sender))
                {
                    TraceLogInvalidTx(transaction, $"WRONG_TRANSACTION_NONCE: {transaction.Nonce} (expected {_stateProvider.GetNonce(sender)})");
                    QuickFail(transaction, block, txTracer, readOnly);
                    return;
                }

                _stateProvider.IncrementNonce(sender);
            }

            _stateProvider.SubtractFromBalance(sender, (ulong) gasLimit * gasPrice, spec);

            // TODO: I think we can skip this commit and decrease the tree operations this way
            _stateProvider.Commit(spec, txTracer.IsTracingState ? txTracer : null);

            long unspentGas = gasLimit - intrinsicGas;
            long spentGas = gasLimit;

            int stateSnapshot = _stateProvider.TakeSnapshot();
            int storageSnapshot = _storageProvider.TakeSnapshot();

            _stateProvider.SubtractFromBalance(sender, value, spec);
            byte statusCode = StatusCode.Failure;
            TransactionSubstate substate = null;

            try
            {
                if (transaction.IsContractCreation)
                {
                    recipient = Address.OfContract(sender, _stateProvider.GetNonce(sender) - 1);
                    if (transaction.IsSystem())
                    {
                        recipient = transaction.SenderAddress;
                    }
                    
                    if (_stateProvider.AccountExists(recipient))
                    {
                        if ((_virtualMachine.GetCachedCodeInfo(recipient)?.MachineCode?.Length ?? 0) != 0 || _stateProvider.GetNonce(recipient) != 0)
                        {
                            if (_logger.IsTrace)
                            {
                                _logger.Trace($"Contract collision at {recipient}"); // the account already owns the contract with the code
                            }

                            throw new TransactionCollisionException();
                        }

                        _stateProvider.UpdateStorageRoot(recipient, Keccak.EmptyTreeHash);
                    }
                }

                bool isPrecompile = recipient.IsPrecompiled(spec);

                ExecutionEnvironment env = new ExecutionEnvironment();
                env.Value = value;
                env.TransferValue = value;
                env.Sender = sender;
                env.CodeSource = recipient;
                env.ExecutingAccount = recipient;
                env.CurrentBlock = block;
                env.GasPrice = gasPrice;
                env.InputData = data ?? new byte[0];
                env.CodeInfo = isPrecompile ? new CodeInfo(recipient) : machineCode == null ? _virtualMachine.GetCachedCodeInfo(recipient) : new CodeInfo(machineCode);
                env.Originator = sender;

                ExecutionType executionType = transaction.IsContractCreation ? ExecutionType.Create : ExecutionType.Call;
                using (EvmState state = new EvmState(unspentGas, env, executionType, isPrecompile, true, false))
                {
                    substate = _virtualMachine.Run(state, txTracer);
                    unspentGas = state.GasAvailable;
                }

                if (substate.ShouldRevert || substate.IsError)
                {
                    if (_logger.IsTrace) _logger.Trace("Restoring state from before transaction");
                    _stateProvider.Restore(stateSnapshot);
                    _storageProvider.Restore(storageSnapshot);
                }
                else
                {
                    // tks: there is similar code fo contract creation from init and from CREATE
                    // this may lead to inconsistencies (however it is tested extensively in blockchain tests)
                    if (transaction.IsContractCreation)
                    {
                        long codeDepositGasCost = CodeDepositHandler.CalculateCost(substate.Output.Length, spec);
                        if (unspentGas < codeDepositGasCost && spec.IsEip2Enabled)
                        {
                            throw new OutOfGasException();
                        }

                        if (unspentGas >= codeDepositGasCost)
                        {
                            Keccak codeHash = _stateProvider.UpdateCode(substate.Output);
                            _stateProvider.UpdateCodeHash(recipient, codeHash, spec);
                            unspentGas -= codeDepositGasCost;
                        }
                    }

                    foreach (Address toBeDestroyed in substate.DestroyList)
                    {
                        if (_logger.IsTrace) _logger.Trace($"Destroying account {toBeDestroyed}");
                        _stateProvider.DeleteAccount(toBeDestroyed);
                    }

                    statusCode = StatusCode.Success;
                }

                spentGas = Refund(gasLimit, unspentGas, substate, sender, gasPrice, spec);
            }
            catch (Exception ex) when (ex is EvmException || ex is OverflowException) // TODO: OverflowException? still needed? hope not
            {
                if (_logger.IsTrace) _logger.Trace($"EVM EXCEPTION: {ex.GetType().Name}");
                _stateProvider.Restore(stateSnapshot);
                _storageProvider.Restore(storageSnapshot);
            }

            if (_logger.IsTrace) _logger.Trace("Gas spent: " + spentGas);

            Address gasBeneficiary = block.GasBeneficiary;
            if (statusCode == StatusCode.Failure || !(substate?.DestroyList.Contains(gasBeneficiary) ?? false))
            {
                if (notSystemTransaction)
                {
                    if (!_stateProvider.AccountExists(gasBeneficiary))
                    {
                        _stateProvider.CreateAccount(gasBeneficiary, (ulong) spentGas * gasPrice);
                    }
                    else
                    {
                        _stateProvider.AddToBalance(gasBeneficiary, (ulong) spentGas * gasPrice, spec);
                    }
                }
            }

            if (!readOnly)
            {
                _storageProvider.Commit(txTracer.IsTracingState ? txTracer : null);
                _stateProvider.Commit(spec, txTracer.IsTracingState ? txTracer : null);
            }
            else
            {
                _storageProvider.Reset();
                _stateProvider.Reset();
            }

            if (!readOnly && notSystemTransaction)
            {
                block.GasUsed += spentGas;
            }

            if (txTracer.IsTracingReceipt)
            {
                if (statusCode == StatusCode.Failure)
                {
                    txTracer.MarkAsFailed(recipient, spentGas, (substate?.ShouldRevert ?? false) ? substate.Output : Bytes.Empty, substate?.Error);
                }
                else
                {
                    txTracer.MarkAsSuccess(recipient, spentGas, substate.Output, substate.Logs.Any() ? substate.Logs.ToArray() : LogEntry.EmptyLogs);
                }
            }
        }
コード例 #57
0
 public PublishTransaction(UInt256 chainhash)
     : base(TransactionType.PublishTransaction, chainhash)
 {
 }
コード例 #58
0
 public KeyAddressTest(string seed, string key, string address, UInt256 r, UInt256 s, byte v)
 {
     Seed    = seed;
     Key     = key;
     Address = address;
     V       = v;
     R       = r;
     S       = s;
 }
コード例 #59
0
ファイル: Account.cs プロジェクト: vkerrysingh/nethermind
 public Account WithChangedBalance(UInt256 newBalance)
 {
     return(new Account(Nonce, newBalance, StorageRoot, CodeHash, IsTotallyEmpty && newBalance.IsZero));
 }
コード例 #60
0
 public MerkleBlockPayload(UInt256 chainhash) : base(chainhash)
 {
 }