예제 #1
0
        public static string MultiSigHashForSigning3(string publickey1, string publickey2, string publickey3, int index, List <TransactionOutput> outputsToSpend, List <TransactionOutput> outputsToSend)
        {
            //get the hash to sign for a single input
            TxIn[] txins = new TxIn[outputsToSpend.Count];

            object[] addresses = new object[3];

            addresses[0] = publickey1;
            addresses[1] = publickey2;
            addresses[2] = publickey3;

            string mscript = MultSigScript(addresses);

            for (int i = 0; i < outputsToSpend.Count; i++)
            {
                if (i == index)
                {
                    txins[i] = new TxIn(HexString.ToByteArrayReversed(outputsToSpend[i].TransactionId), (uint)outputsToSpend[i].OutputIndex, HexString.ToByteArray(mscript));
                }
                else
                {
                    txins[i] = new TxIn(HexString.ToByteArrayReversed(outputsToSpend[i].TransactionId), (uint)outputsToSpend[i].OutputIndex, new Byte[0]);
                };
            }


            TxOut[] txouts = new TxOut[outputsToSend.Count];

            HashType hashType = HashType.SIGHASH_ALL;

            int j = 0;

            foreach (TransactionOutput outp in outputsToSend)
            {
                //PublicKey pkPayTo = new PublicKey(HexString.ToByteArray(outp.Address));
                Address addr    = new Address(outp.Address);
                Script  scPayTo = ScriptTemplate.PayToAddress(addr);

                TxOut toutSpend = new TxOut((ulong)outp.Amount, scPayTo.ToBytes());

                txouts[j] = toutSpend;
                j++;
            }


            //create the new transaction to spend the coins at the multisig address
            Transaction tx = new Transaction(1, txins, txouts, 0);

            //clone the transaction
            //Transaction txCopy = new Transaction(tx.ToBytes());

            SHA256 sha256 = SHA256.Create();

            //hash the transaction with some leading bytes
            Byte[] txHash = tx.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray();
            txHash = sha256.ComputeHash(sha256.ComputeHash(txHash));

            return(HexString.FromByteArray(txHash));
        }
예제 #2
0
        public static string MultiSig2Of3TransactionForTesting(string publickey1, string publickey2, string publickey3, string privKey1, string privKey2, string transactionid, uint prevoutIndex, string toAddress, ulong amount)
        {
            TxIn[]  txins  = new TxIn[1];
            TxOut[] txouts = new TxOut[1];

            byte version = 0;

            //PayToAddress
            HashType hashType = HashType.SIGHASH_ALL;

            PublicKey pk = new PublicKey(HexString.ToByteArray(toAddress));
            //Address add = new Address(pk.);

            //address to send coins to
            // string dec = HexString.FromByteArray(Base58CheckString.ToByteArray(add.ToString(), out version));


            //create address

            //create script to pay to address
            Script sc = ScriptTemplate.PayToAddress(pk.address);

            //create transaction output
            TxOut tout = new TxOut(amount - 5, sc.ToBytes());

            txouts[0] = tout;

            object[] addresses = new object[3];

            addresses[0] = publickey1;
            addresses[1] = publickey2;
            addresses[2] = publickey3;

            string mscript = MultSigScript(addresses);


            //create input based on previous output to spend
            //and the redeem script for the multi-sig address
            TxIn tin = new TxIn(HexString.ToByteArrayReversed(transactionid), prevoutIndex, HexString.ToByteArray(mscript));

            txins[0] = tin;

            //basically the redeem script
            Script subScript = new Script(tin.scriptSig);

            //create the new transaction to spend the coins at the multisig address
            Transaction tx = new Transaction(1, txins, txouts, 0);

            //clone the transaction
            Transaction txCopy = new Transaction(tx.ToBytes());

            SHA256 sha256 = SHA256.Create();

            //hash the transaction with some leading bytes
            Byte[] txHash = txCopy.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray();
            txHash = sha256.ComputeHash(sha256.ComputeHash(txHash));

            //get the private keys bytes 1-33 and base58
            byte[]     test58 = Base58String.ToByteArray(privKey1).Skip(1).Take(32).ToArray();
            ECKeyPair  key1   = new ECKeyPair(test58, null, false);
            PrivateKey pk1    = new PrivateKey(key1);

            byte[]     test582 = Base58String.ToByteArray(privKey2).Skip(1).Take(32).ToArray();
            ECKeyPair  key2    = new ECKeyPair(test582, null, false);
            PrivateKey pk2     = new PrivateKey(key2);



            //Script scriptSig = new Script(tin.scriptSig);

            //sign the transaction hash
            Byte[] sig  = pk1.Sign(txHash).Concat(new Byte[] { (Byte)hashType }).ToArray();
            Byte[] sig2 = pk2.Sign(txHash).Concat(new Byte[] { (Byte)hashType }).ToArray();

            //create a new script to sign
            Script s = new Script(new Byte[] { 0x00 });

            //add the signatures to the script
            s.elements.Add(new ScriptElement(sig));
            s.elements.Add(new ScriptElement(sig2));

            //txtResult.Text = HexString.FromByteArray(tx.ToBytes());

            //add the original multisig script
            s.elements.Add(new ScriptElement(tin.scriptSig));

            //overwrite the script on the transaction with the new signatures + script
            tin.scriptSig = s.ToBytes();

            return(HexString.FromByteArray(tx.ToBytes()));
        }
예제 #3
0
        //switched to user key pair directly

        public static bool VerifySignature(string key, string message, string sig)
        {
            PublicKey pk1 = new PublicKey(HexString.ToByteArray(key));

            return(pk1.VerifySignature(HexString.ToByteArray(message), HexString.ToByteArray(sig)));
        }
예제 #4
0
        //public static string MultiSigHashForSigning2(string publickey1, string publickey2, string publickey3, string transactionid, uint prevoutIndex, List<TransactionOutput> outputsToSend)
        //{

        //    //get the hash to sign for a single input
        //    TxIn[] txins = new TxIn[1];
        //    TxOut[] txouts = new TxOut[outputsToSend.Count];

        //    HashType hashType = HashType.SIGHASH_ALL;

        //    int i = 0;
        //    foreach (TransactionOutput outp in outputsToSend)
        //    {
        //        //PublicKey pkPayTo = new PublicKey(HexString.ToByteArray(outp.Address));
        //        Address addr = new Address(outp.Address);
        //        Script scPayTo = ScriptTemplate.PayToAddress(addr);

        //        TxOut toutSpend = new TxOut((ulong)outp.Amount, scPayTo.ToBytes());

        //        txouts[i] = toutSpend;
        //        i++;
        //    }


        //    object[] addresses = new object[3];

        //    addresses[0] = publickey1;
        //    addresses[1] = publickey2;
        //    addresses[2] = publickey3;



        //    string mscript = MultSigScript(addresses);


        //    //create input based on previous output to spend
        //    //and the redeem script for the multi-sig address
        //    TxIn tin = new TxIn(HexString.ToByteArrayReversed(transactionid), prevoutIndex, HexString.ToByteArray(mscript));
        //    txins[0] = tin;

        //    Script multScript = ScriptTemplate.MultiSig(addresses);

        //    Address address = new Address(multScript.ToBytes(), Address.SCRIPT);

        //    Console.WriteLine(address.ToString());

        //    //basically the redeem script
        //    Script subScript = new Script(tin.scriptSig);

        //    //create the new transaction to spend the coins at the multisig address
        //    Transaction tx = new Transaction(1, txins, txouts, 0);

        //    //clone the transaction
        //    //Transaction txCopy = new Transaction(tx.ToBytes());

        //    SHA256 sha256 = new SHA256Managed();

        //    //hash the transaction with some leading bytes
        //    Byte[] txHash = tx.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray();
        //    txHash = sha256.ComputeHash(sha256.ComputeHash(txHash));

        //    return HexString.FromByteArray(txHash);

        //}
        //public static string MultiSigHashForSigning(string publickey1, string publickey2, string publickey3, string transactionid, uint prevoutIndex, string toAddress, ulong amount)
        //{
        //    TxIn[] txins = new TxIn[1];
        //    TxOut[] txouts = new TxOut[1];

        //    byte version = 0;

        //    //PayToAddress
        //    HashType hashType = HashType.SIGHASH_ALL;

        //    PublicKey pk = new PublicKey(HexString.ToByteArray(toAddress));
        //    //Address add = new Address(pk.);

        //    //address to send coins to
        //    // string dec = HexString.FromByteArray(Base58CheckString.ToByteArray(add.ToString(), out version));


        //    //create address

        //    //create script to pay to address
        //    Script sc = ScriptTemplate.PayToAddress(pk.address);

        //    //create transaction output
        //    TxOut tout = new TxOut(amount - 5, sc.ToBytes());
        //    txouts[0] = tout;

        //    object[] addresses = new object[3];

        //    addresses[0] = publickey1;
        //    addresses[1] = publickey2;
        //    addresses[2] = publickey3;

        //    string mscript = MultSigScript(addresses);


        //    //create input based on previous output to spend
        //    //and the redeem script for the multi-sig address
        //    TxIn tin = new TxIn(HexString.ToByteArrayReversed(transactionid), prevoutIndex, HexString.ToByteArray(mscript));
        //    txins[0] = tin;

        //    //basically the redeem script
        //    Script subScript = new Script(tin.scriptSig);

        //    //create the new transaction to spend the coins at the multisig address
        //    Transaction tx = new Transaction(1, txins, txouts, 0);

        //    //clone the transaction
        //    Transaction txCopy = new Transaction(tx.ToBytes());

        //    SHA256 sha256 = new SHA256Managed();

        //    //hash the transaction with some leading bytes
        //    Byte[] txHash = txCopy.ToBytes().Concat(new Byte[] { (Byte)hashType, 0x00, 0x00, 0x00 }).ToArray();
        //    txHash = sha256.ComputeHash(sha256.ComputeHash(txHash));

        //    return HexString.FromByteArray(txHash);
        //}
        public static string MultiSig2Of3Transaction(string[] ninkiSigs, string[] userSigs, List <string[]> publicKeys, List <TransactionOutput> outputsToSpend, List <TransactionOutput> outputsToSend)
        {
            TxIn[]      txins  = new TxIn[outputsToSpend.Count];
            TxOut[]     txouts = new TxOut[outputsToSend.Count];
            Transaction tx     = new Transaction(1, txins, txouts, 0);

            int i = 0;

            foreach (TransactionOutput outSpend in outputsToSpend)
            {
                string[] pubkeys = publicKeys[i];
                string   mscript = MultSigScript(pubkeys);
                //create input based on previous output to spend
                //and the redeem script for the multi-sig address
                TxIn tin = new TxIn(HexString.ToByteArrayReversed(outSpend.TransactionId), (uint)outSpend.OutputIndex, HexString.ToByteArray(mscript));
                txins[i] = tin;

                Script s = new Script(new Byte[] { 0x00 });
                //add the signatures to the script

                //this check is to support returning transactions for testing
                if (ninkiSigs != null)
                {
                    s.elements.Add(new ScriptElement(HexString.ToByteArray(ninkiSigs[i])));
                }
                if (userSigs != null)
                {
                    s.elements.Add(new ScriptElement(HexString.ToByteArray(userSigs[i])));
                }


                //txtResult.Text = HexString.FromByteArray(tx.ToBytes());

                //add the original multisig script
                s.elements.Add(new ScriptElement(tin.scriptSig));

                //overwrite the script on the transaction with the new signatures + script
                tin.scriptSig = s.ToBytes();

                i++;
            }

            i = 0;
            foreach (TransactionOutput outSend in outputsToSend)
            {
                Address add = new Address(outSend.Address);
                Script  sc  = ScriptTemplate.PayToAddress(add);
                //create transaction output
                TxOut tout = new TxOut((ulong)outSend.Amount, sc.ToBytes());
                txouts[i] = tout;
                i++;
            }

            return(HexString.FromByteArray(tx.ToBytes()));
        }
예제 #5
0
 public static string MultSigScript(object[] addresses)
 {
     return(HexString.FromByteArray(ScriptTemplate.MultiSig(addresses).ToBytes()));
 }
예제 #6
0
 public static PublicKey FromHex(String s)
 {
     return(new PublicKey(HexString.ToByteArray(s)));
 }
예제 #7
0
        public BIP32 DeriveChildPrivateOnly(uint i)
        {
            DateTime start = DateTime.Now;

            BIP32 ret = new BIP32(secp256k1);

            byte[] ib;

            using (MemoryStream ms = new MemoryStream())
            using (BinaryWriter bw = new BinaryWriter(ms))
            {
                bw.Write((byte)((i >> 24) & 0xff));
                bw.Write((byte)((i >> 16) & 0xff));
                bw.Write((byte)((i >> 8) & 0xff));
                bw.Write((byte)(i & 0xff));
                ib = ms.ToArray();
            }


            bool use_private = (i & 0x80000000) != 0;

            bool is_private =
                (this.version == BITCOIN_MAINNET_PRIVATE ||
                 this.version == BITCOIN_TESTNET_PRIVATE);

            if (use_private && (this.eckey.privKey == null || !is_private)) throw new Exception("Cannot do private key derivation without private key");


            if (this.eckey.privKey != null)
            {
                byte[] data = null;
                using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    if (use_private)
                    {
                        bw.Write((byte)0);
                        bw.Write(this.eckey.privKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                    else
                    {
                        //bw.Write((byte)0);
                        bw.Write(this.eckey.pubKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                }

                HMACSHA512 hmacsha = new HMACSHA512(this.chain_code);
                byte[] hash = hmacsha.ComputeHash(data);

                string hhash = HexString.FromByteArray(hash);

                byte[] ir = HexString.ToByteArray(hhash.Substring(64, 64));

                string ilb = hhash.Substring(0, 64);
                string pkb = HexString.FromByteArray(this.eckey.privKey);
               
                string k = secp256k1.AddPrivate(pkb, ilb);

                ret.chain_code = ir;
                ret.eckey = new ECKeyPair(HexString.ToByteArray(k),null,false,true);

            }
            else
            {

            }

            ret.child_index = i;

            //this is why we need the pub key hash
            //for the fingerprint

            Address add = new Address(this.eckey.pubKey);
            ret.parent_fingerprint = add.PubKeyHash.hash.Take(4).ToArray();

            ret.version = this.version;
            ret.depth = this.depth + 1;

            ret.BuildExtendedPublicKey();
            return ret;

        }
예제 #8
0
        public BIP32 DeriveChild(uint i)
        {
            DateTime start = DateTime.Now;

            BIP32 ret = new BIP32(secp256k1);

            byte[] ib;

            using (MemoryStream ms = new MemoryStream())
            using (BinaryWriter bw = new BinaryWriter(ms))
            {
                bw.Write((byte)((i >> 24) & 0xff));
                bw.Write((byte)((i >> 16) & 0xff));
                bw.Write((byte)((i >> 8) & 0xff));
                bw.Write((byte)(i & 0xff));
                ib = ms.ToArray();
            }


            bool use_private = (i & 0x80000000) != 0;

            bool is_private =
                (this.version == BITCOIN_MAINNET_PRIVATE ||
                 this.version == BITCOIN_TESTNET_PRIVATE);

            if (use_private && (this.eckey.privKey == null || !is_private)) throw new Exception("Cannot do private key derivation without private key");


            if (this.eckey.privKey != null)
            {
                byte[] data = null;
                using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    if (use_private)
                    {
                        bw.Write((byte)0);
                        bw.Write(this.eckey.privKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                    else
                    {
                        //bw.Write((byte)0);
                        bw.Write(this.eckey.pubKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                }



                HMACSHA512 hmacsha = new HMACSHA512(this.chain_code);
                byte[] hash = hmacsha.ComputeHash(data);

                string hhash = HexString.FromByteArray(hash);

                byte[] ir = HexString.ToByteArray(hhash.Substring(64, 64));

                string ilb = hhash.Substring(0, 64);
                string pkb = HexString.FromByteArray(this.eckey.privKey);

                string k = secp256k1.AddPrivate(pkb, ilb);

                ret.chain_code = ir;

                byte[] derkey = HexString.ToByteArray(k);

                if (derkey.Length == 31)
                {
                    List<byte> tmp = derkey.ToList();
                    tmp.Insert(0, (byte)0);
                    derkey = tmp.ToArray();
                }

                ret.eckey = new ECKeyPair(derkey, null, false, false, secp256k1);
                ret.eckey.compress(true);
      
            }
            else
            {

                byte[] data = null;
                using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    if (use_private)
                    {
                        bw.Write((byte)0);
                        bw.Write(this.eckey.privKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                    else
                    {
                        //bw.Write((byte)3);
                        bw.Write(this.eckey.pubKey);
                        bw.Write(ib);
                        data = ms.ToArray();
                    }
                }

                HMACSHA512 hmacsha = new HMACSHA512(this.chain_code);
                byte[] hash = hmacsha.ComputeHash(data);

                string test = HexString.FromByteArray(hash);

                byte[] ir = HexString.ToByteArray(test.Substring(64, 64));

                string bil = test.Substring(0, 64);
                string bpub = HexString.FromByteArray(this.eckey.pubKey);
                string point = secp256k1.AddPublic(bpub, bil);
                
                ret.chain_code = ir;
                ret.eckey = new ECKeyPair(null, HexString.ToByteArray(point));
 
                ret.eckey.compress(true);
            }

            ret.child_index = i;

            //this is why we need the pub key hash
            //for the fingerprint
            start = DateTime.Now;
            Address add = new Address(this.eckey.pubKey);
            Console.WriteLine("New Address:" + DateTime.Now.Subtract(start).TotalMilliseconds);


            ret.parent_fingerprint = add.PubKeyHash.hash.Take(4).ToArray();

            ret.version = this.version;
            ret.depth = this.depth + 1;

            ret.BuildExtendedPublicKey();
            ret.BuildExtendedPrivateKey();

            return ret;

        }