示例#1
0
        /// <summary>
        /// Generate atomic swap payment script to P2PKH <paramref name="bobAddress"/> with multisig refund
        /// </summary>
        /// <param name="aliceRefundPubKey">Alice public key for refund</param>
        /// <param name="bobRefundPubKey">Bob public key for refund</param>
        /// <param name="bobAddress">Bob target address</param>
        /// <param name="secretHash">Secret hash</param>
        /// <param name="expectedNetwork">Expected network necessary to get the correct hash address</param>
        /// <returns>Atomic swap payment script</returns>
        public static Script GenerateP2PkhSwapPayment(
            byte[] aliceRefundPubKey,
            byte[] bobRefundPubKey,
            string bobAddress,
            byte[] secretHash,
            Network expectedNetwork = null)
        {
            // OP_IF
            //    2 <aliceRefundPubKey> <bobRefundPubKey> 2 CHECKMULTISIG
            // OP_ELSE
            //    OP_HASH256 <secretHash> OP_EQUALVERIFY OP_DUP OP_HASH160 <bobAddress> OP_EQUALVERIFY OP_CHECKSIG
            // OP_ENDIF

            if (aliceRefundPubKey == null)
            {
                throw new ArgumentNullException(nameof(aliceRefundPubKey));
            }

            if (bobRefundPubKey == null)
            {
                throw new ArgumentNullException(nameof(bobRefundPubKey));
            }

            if (bobAddress == null)
            {
                throw new ArgumentNullException(nameof(bobAddress));
            }

            if (secretHash == null)
            {
                throw new ArgumentNullException(nameof(secretHash));
            }

            var bobAddressHash = new BitcoinPubKeyAddress(bobAddress, expectedNetwork).Hash;

            return(new Script(new List <Op>
            {
                OpcodeType.OP_IF,
                Op.GetPushOp(2),
                Op.GetPushOp(aliceRefundPubKey),
                Op.GetPushOp(bobRefundPubKey),
                Op.GetPushOp(2),
                OpcodeType.OP_CHECKMULTISIG,
                OpcodeType.OP_ELSE,
                OpcodeType.OP_HASH256,
                Op.GetPushOp(secretHash),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_DUP,
                OpcodeType.OP_HASH160,
                Op.GetPushOp(bobAddressHash.ToBytes()),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_CHECKSIG,
                OpcodeType.OP_ENDIF
            }));
        }
示例#2
0
        /// <summary>
        /// Generate atomic swap payment script to P2PKH <paramref name="bobAddress"/> with HTLC refund and secret size check
        /// </summary>
        /// <param name="aliceRefundAddress">Alice refund address</param>
        /// <param name="bobAddress">Bob target address</param>
        /// <param name="lockTimeStamp">Lock TimeStamp for refund</param>
        /// <param name="secretHash">Secret hash</param>
        /// <param name="secretSize">Secret size in bytes</param>
        /// <param name="expectedNetwork">Expected network necessary to get the correct hash addresses</param>
        /// <returns>Atomic swap payment script</returns>
        public static Script GenerateHtlcP2PkhSwapPayment(
            string aliceRefundAddress,
            string bobAddress,
            long lockTimeStamp,
            byte[] secretHash,
            int secretSize,
            Network expectedNetwork = null)
        {
            // OP_IF
            //    <lockTimeStamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <aliceRefundAddress> OP_EQUALVERIFY CHECKSIG
            // OP_ELSE
            //    OP_SIZE <secretSize> OP_EQUALVERIFY OP_HASH256 <secretHash> OP_EQUALVERIFY OP_DUP OP_HASH160 <bobAddress> OP_EQUALVERIFY OP_CHECKSIG
            // OP_ENDIF

            if (aliceRefundAddress == null)
            {
                throw new ArgumentNullException(nameof(aliceRefundAddress));
            }

            if (bobAddress == null)
            {
                throw new ArgumentNullException(nameof(bobAddress));
            }

            if (secretHash == null)
            {
                throw new ArgumentNullException(nameof(secretHash));
            }

            if (secretSize <= 0)
            {
                throw new ArgumentException("Invalid Secret Size", nameof(secretSize));
            }

            var aliceRefundAddressHash = new BitcoinPubKeyAddress(aliceRefundAddress, expectedNetwork).Hash;
            var bobAddressHash         = new BitcoinPubKeyAddress(bobAddress, expectedNetwork).Hash;

            return(new Script(new List <Op>
            {
                // if refund
                OpcodeType.OP_IF,
                Op.GetPushOp(lockTimeStamp),
                OpcodeType.OP_CHECKLOCKTIMEVERIFY,
                OpcodeType.OP_DROP,
                OpcodeType.OP_DUP,
                OpcodeType.OP_HASH160,
                Op.GetPushOp(aliceRefundAddressHash.ToBytes()),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_CHECKSIG,
                // else redeem
                OpcodeType.OP_ELSE,
                OpcodeType.OP_SIZE,
                Op.GetPushOp(secretSize),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_HASH256,
                Op.GetPushOp(secretHash),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_DUP,
                OpcodeType.OP_HASH160,
                Op.GetPushOp(bobAddressHash.ToBytes()),
                OpcodeType.OP_EQUALVERIFY,
                OpcodeType.OP_CHECKSIG,
                OpcodeType.OP_ENDIF
            }));
        }