Beispiel #1
0
        public OperatingError VerifyMultisig(MultiSig multisig, UInt256 hash, bool useNewChainId)
        {
            /* don't allow null multisig or hash */
            if (multisig is null || hash is null)
            {
                Logger.LogDebug("Multisig or hash is null");
                return(OperatingError.InvalidMultisig);
            }
            /* check that all signatures are unique */
            if (multisig.Signatures.Select(sig => sig.Key).Distinct().Count() != multisig.Signatures.Count)
            {
                Logger.LogDebug("Duplicate signature in multisig");
                return(OperatingError.InvalidMultisig);
            }
            /* check count of unique validators */
            if (multisig.Validators.Distinct().Count() != multisig.Validators.Count)
            {
                Logger.LogDebug("Duplicate validator in multisig");
                return(OperatingError.InvalidMultisig);
            }
            /* verify every validator's signature */
            var verified = 0;

            foreach (var entry in multisig.Signatures)
            {
                /* if there is no validator's public key than skip it */
                if (!multisig.Validators.Contains(entry.Key))
                {
                    continue;
                }
                var publicKey = entry.Key.EncodeCompressed();
                var sig       = entry.Value.Encode();
                try
                {
                    /* if signature invalid that skip it */
                    if (!_crypto.VerifySignatureHashed(hash.ToBytes(), sig, publicKey, useNewChainId))
                    {
                        Logger.LogWarning($"Invalid Multisig signature: hash: {hash.ToHex()}, sig: {sig.ToHex()}, publicKey: {publicKey.ToHex()}");
                        continue;
                    }
                    /* increment count of verified signatures */
                    ++verified;
                }
                catch (System.Exception)
                {
                    // ignore
                }
            }

            // if we have required amount of signatures that return ok
            if (verified < multisig.Quorum)
            {
                Logger.LogWarning($"Quorum not reached: {verified} < {multisig.Quorum}");
            }
            return(verified >= multisig.Quorum ? OperatingError.Ok : OperatingError.QuorumNotReached);
        }
Beispiel #2
0
        public void TxDebug(uint path, params string[] seed)
        {
            Transaction   tx     = new Transaction("01000000000101fb1db914dd2be5311ebde6f86f1d49551057557fa22021a3a59623fa086836b2000000002322002029ccc4c03f9609ff9f79b0b7d3ade093ffd7da6d37c06edc65bfb898d4aee069ffffffff01e01dbe070000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc87040047304402204e4c8a3ebf889821e574edb805bb6b65523e5a000ee4729db7e7d2888741c5830220058df53eb3b6f052a8dab2f897901d85242297dfa6aafebeb577913c2782c16a01483045022100f03b655ffedbd262f98ed3a562b32bc676e565b457f3fe89f557b755f4ab0d7502200e6c3006351a220c8fcf0a563701537b8979ceb289170d16ff8da760083a62c80147522103a0b99131aca0a5c696fe9f7e63b987f185050d2e6b25f80731f9f0ab83702d862102103f9e18fb85e862a20ff9d7afb0172661296f08d988508a538a68c96a1c4a5752ae00000000");
            List <ExtKey> keys   = new List <ExtKey>();
            Segwit        segwit = new Segwit(NBitcoin.Network.TestNet);

            for (int i = 0; i < seed.Length; i++)
            {
                var key     = GetKey(path, seed[i]);
                var address = segwit.GetP2SHAddress(key);
                keys.Add(key);
                //Console.WriteLine(address.ToString());
            }

            MultiSig multi = new MultiSig(NBitcoin.Network.TestNet);
            var      p2sh  = multi.GetP2SHAddress(2, keys.ToArray());

            Console.WriteLine(p2sh.ToString());
        }
        private (BlockHeader, MultiSig) BuildHeaderAndMultisig(UInt256 merkleRoot, Block?predecessor,
                                                               UInt256 stateHash)
        {
            var blockIndex = predecessor !.Header.Index + 1;
            var header     = new BlockHeader
            {
                Index         = blockIndex,
                PrevBlockHash = predecessor !.Hash,
                MerkleRoot    = merkleRoot,
                StateHash     = stateHash,
                Nonce         = blockIndex
            };

            var keyPair = _privateWallet.EcdsaKeyPair;

            var headerSignature = Crypto.SignHashed(
                header.Keccak().ToBytes(),
                keyPair.PrivateKey.Encode(), HardforkHeights.IsHardfork_9Active(blockIndex)
                ).ToSignature(HardforkHeights.IsHardfork_9Active(blockIndex));

            var multisig = new MultiSig
            {
                Quorum     = 1,
                Validators = { _privateWallet.EcdsaKeyPair.PublicKey },
                Signatures =
                {
                    new MultiSig.Types.SignatureByValidator
                    {
                        Key   = _privateWallet.EcdsaKeyPair.PublicKey,
                        Value = headerSignature,
                    }
                }
            };

            return(header, multisig);
        }
Beispiel #4
0
 public BlockBuilder WithMultisig(MultiSig multiSig)
 {
     _multiSig = multiSig;
     return(this);
 }
Beispiel #5
0
        public void CreateBasicSwap(uint path, params string[] seed)
        {
            List <ExtKey> keys   = new List <ExtKey>();
            Segwit        segwit = new Segwit(NBitcoin.Network.TestNet);

            for (int i = 0; i < seed.Length; i++)
            {
                var key     = GetKey(path, seed[i]);
                var address = segwit.GetP2SHAddress(key);
                keys.Add(key);
                //Console.WriteLine(address.ToString());
            }

            MultiSig multi = new MultiSig(NBitcoin.Network.TestNet);
            var      p2sh  = multi.GetP2SHAddress(2, keys.ToArray());

            Console.WriteLine(p2sh.ToString());
            //multi: b2366808fa2396a5a32120a27f55571055491d6ff8e6bd1e31e52bdd14b91dfb

            REST.BlockExplorer explorer = new REST.BlockExplorer("https://testnet.blockexplorer.com/");

            //var tx = explorer.GetTransaction("b2366808fa2396a5a32120a27f55571055491d6ff8e6bd1e31e52bdd14b91dfb");

            var response = explorer.GetUnspent(p2sh.ToString());
            List <ExplorerUnspent> unspent      = response.Convert <List <ExplorerUnspent> >();
            List <Transaction>     transactions = new List <Transaction>();

            foreach (var item in unspent)
            {
                ExplorerResponse txResponse = explorer.GetTransaction(item.txid);
                RawFormat        format     = RawFormat.Satoshi;
                var tx = Transaction.Parse(txResponse.data, format, Network.TestNet);
                transactions.Add(tx);
            }
            //Create send transaction.

            //get redeem script
            var         redeemScript = multi.GetRedeemScript(2, keys.ToArray());
            Transaction received     = transactions[0];
            ScriptCoin  coin         = received.Outputs.AsCoins().First().ToScriptCoin(redeemScript);

            //create transaction:

            BitcoinAddress     destination = BitcoinAddress.Create("2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF"); //the faucet return address
            TransactionBuilder builder     = new TransactionBuilder();

            builder.AddCoins(coin);
            builder.Send(destination, Money.Coins(1.299m));
            builder.SendFees(Money.Coins(0.001m));
            builder.SetChange(destination);
            //builder.
            var unsigned = builder.BuildTransaction(sign: false);

            var         signedA = builder.AddCoins(coin).AddKeys(keys[0].PrivateKey).SignTransaction(unsigned);
            Transaction signedB = builder.AddCoins(coin).AddKeys(keys[1].PrivateKey).SignTransaction(signedA);

            Transaction fullySigned = builder.AddCoins(coin).CombineSignatures(signedA, signedB);

            Console.WriteLine(fullySigned.ToHex());
            Console.ReadLine();
        }
Beispiel #6
0
        public void NewCreateBasicSwap(uint path, params string[] seed)
        {
            List <ExtKey> keys   = new List <ExtKey>();
            Segwit        segwit = new Segwit(NBitcoin.Network.TestNet);

            for (int i = 0; i < seed.Length; i++)
            {
                var key = GetKey(path, seed[i]);
                //var address = segwit.GetP2SHAddress(key);
                keys.Add(key);
                //Console.WriteLine(address.ToString());
            }
            NBitcoin.Network _Network = NBitcoin.Network.TestNet;

            MultiSig      multi   = new MultiSig(NBitcoin.Network.TestNet);
            List <PubKey> pubKeys = new List <PubKey>();

            for (int i = 0; i < keys.Count; i++)
            {
                pubKeys.Add(keys[i].PrivateKey.PubKey);
            }
            Script pubKeyScript = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, pubKeys.ToArray());

            BitcoinAddress       address = pubKeyScript.WitHash.GetAddress(_Network);
            BitcoinScriptAddress p2sh    = address.GetScriptAddress();

            Console.WriteLine("Send money here: " + p2sh.ToString());
            REST.BlockExplorer explorer = new REST.BlockExplorer("https://testnet.blockexplorer.com/");
            var response = explorer.GetUnspent(p2sh.ToString());
            List <ExplorerUnspent> unspent      = response.Convert <List <ExplorerUnspent> >();
            List <Transaction>     transactions = new List <Transaction>();

            foreach (var item in unspent)
            {
                ExplorerResponse txResponse = explorer.GetTransaction(item.txid);
                RawFormat        format     = RawFormat.Satoshi;
                var tx = Transaction.Parse(txResponse.data, format, Network.TestNet);
                transactions.Add(tx);
            }
            //Create send transaction.

            //get redeem script
            //var redeemScript = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, pubKeys.ToArray());// multi.GetRedeemScript(2, keys.ToArray());

            Transaction received = transactions[0];
            ScriptCoin  coin     = received.Outputs.AsCoins().First().ToScriptCoin(pubKeyScript.WitHash.ScriptPubKey.Hash.ScriptPubKey);
            //create transaction:
            BitcoinAddress     destination = BitcoinAddress.Create("2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF"); //the faucet return address
            TransactionBuilder builder     = new TransactionBuilder();

            builder.AddCoins(coin);
            builder.Send(destination, Money.Coins(1.299m));
            builder.SendFees(Money.Coins(0.001m));
            builder.SetChange(destination);
            //builder.
            var unsigned = builder.BuildTransaction(sign: false);

            var         signedA = builder.AddCoins(coin).AddKeys(keys[0].PrivateKey).SignTransaction(unsigned);
            Transaction signedB = builder.AddCoins(coin).AddKeys(keys[1].PrivateKey).SignTransaction(signedA);

            Transaction fullySigned = builder.AddCoins(coin).CombineSignatures(signedA, signedB);

            Console.WriteLine(fullySigned.ToHex());
            Console.ReadLine();
        }
Beispiel #7
0
        // After sufficient votes are on the emulated stateHash, the block is approved and
        // executed to add to the chain
        public void ProduceBlock(IEnumerable <TransactionReceipt> receipts, BlockHeader header, MultiSig multiSig)
        {
            Logger.LogDebug($"Producing block {header.Index}");
            if (_blockManager.GetHeight() >= header.Index)
            {
                Logger.LogWarning("Block already produced");
                return;
            }
            var blockWithTransactions = new BlockBuilder(_blockManager.LatestBlock().Header, header.StateHash)
                                        .WithTransactions(receipts)
                                        .WithMultisig(multiSig)
                                        .Build(header.Nonce);

            Logger.LogDebug($"Block approved by consensus: {blockWithTransactions.Block.Hash.ToHex()}");
            if (_blockManager.GetHeight() + 1 != header.Index)
            {
                throw new InvalidOperationException(
                          $"Current height is {_blockManager.GetHeight()}, but we are trying to produce block {header.Index}"
                          );
            }

            var result = _blockManager.Execute(
                blockWithTransactions.Block, blockWithTransactions.Transactions, commit: true,
                checkStateHash: true);

            if (result != OperatingError.Ok)
            {
                Logger.LogError(
                    $"Block {blockWithTransactions.Block.Header.Index} ({blockWithTransactions.Block.Hash.ToHex()}) was not persisted: {result}"
                    );
                Logger.LogTrace($"Block raw data: {blockWithTransactions.Block.ToByteArray().ToHex()}");
                Logger.LogTrace($"Block transactions data: {string.Join(", ", blockWithTransactions.Transactions.Select(tx => tx.ToByteArray().ToHex()))}");
            }
        }