Qitmeer 原子交换技术实现

Qitmeer 原子交换技术实现

哈希时间锁定合约(HTLC)技术介绍

HTLC(哈希时间锁协议)是一种特定类型的支付渠道,可以交换两种不同的加密资产。交易双方按发布各自的哈希时间锁合约,通过交换解锁秘钥取走对方合约中的资产,完成跨链资产交换,使用 HTLC 协议完成跨链交换的好处是整个过程不需要第三方参与,保证交易双方资产安全性。

哈希时间锁的工作原理如下:

Alice 持有 MEER ,需求 MEER -> BTC;
Bob 持有 BTC ,需求 BTC -> MEER;
交易由 Alice 发起;
  1. Alice 在本地创建 解锁秘钥(Secret Key)及 (Secret Key Hash),我们一般在 UTXO 链之间使用 RIPEMD160 算法,ETH 主链是 sha256。
  2. Alice 使用 Secret Key 生成时间锁合约 contract-MEER。
  3. Alice 转入 10 个 MEER 到时间锁合约地址。
  4. Bob 校验时间锁合约时间及地址,并使用 Secret Key Hash 在 BTC 上创建对应的时间锁合约 contract-BTC。
  5. Alice 使用 Secret Key 将 contract-BTC 合约中的 BTC 取走。
  6. Bob 通过 Secret Key 将 Alice contract-MEER 合约中的 MEER 取走。
  7. 双方完成交易,无需相互信任。
  8. 交易过程中,若双方未在规定时间内完成交易,则时间锁合约创建者可以将合约中的代币取回,避免损失。

准备工具:

实现 1 :MEER 和 BTC 原子互换

本文将使用 qx 命令 和 bx 命令 完成合约创建工作。

步骤 1 交易双方准备地址

Alice MEER PublicKeyHash = 8dc268a8e2876b941b95f3bd3b71050f003c5383;
Alice BTC PublicKeyHash = 843043481f636dafd10cb0433d4f34456eb3c840
Alice BTC Address = msZuJjb9m8pDMRNDRvaYCz9JcLTQt58RCZ;
Alice MEER Address = TmbsdsjwzuGboFQ9GcKg6EUmrr3tokzozyF;

Bob MEER PublicKeyHash  = cdd006e3adcd991a15f46c7e975686c1aec20773;
Bob BTC PublicKeyHash  = 46d96e0eb3f7de705b860347e451b9c41af72cd2;
Bob BTC Address = mmya4n31E5TZodgWxrtn3nXQhU2HLZA19E;
Bob MEER Address = TmhiKSDgr8SrGxEe7v6ee1TWY4FA6Nq5AQL;

步骤 2 Secret Key 和 Secret Key Hash

Alice 需要创建自己的 Secret Key 和 Secret Key Hash;

qx entropy

Secret Key

7bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa

生成 Secret Key Hash

qx ripemd160 7bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa

Secret Key Hash

b75e2a5d3954e063a1de032caa7baed1029fa1e9

步骤 3 创建合约

哈希时间锁合约必须包含 hash 锁和 时间锁,标准 OP 合约如下:

OP_IF
    OP_RIPEMD160 
    # Secret Key Hash
    b75e2a5d3954e063a1de032caa7baed1029fa1e9 OP_EQUALVERIFY
    OP_DUP OP_HASH160 
    # Bob MEER PublicKeyHash
    cdd006e3adcd991a15f46c7e975686c1aec20773 
OP_ELSE
    # 2019.08.03 00:00:00
    005e445d 
    OP_CHECKLOCKTIMEVERIFY
    OP_DROP OP_DUP OP_HASH160 
    # Alice PublicKeyHash
    8dc268a8e2876b941b95f3bd3b71050f003c5383 
OP_ENDIF OP_EQUALVERIFY OP_CHECKSIG

该合约表示 Bob 若能提供 秘钥,该秘钥 RIPEMD160 后能得到 b75e2a5d3954e063a1de032caa7baed1029fa1e9 就可以花费该笔交易,若超过 2019.08.03 00:00:00 未花费,则 Alice 可以花费该笔交易。

通过 bx 工具,我们可以生产合约脚本;

bx script-encode "if ripemd160 [b75e2a5d3954e063a1de032caa7baed1029fa1e9] equalverify dup hash160 [cdd006e3adcd991a15f46c7e975686c1aec20773] else [005e445d] checklocktimeverify drop dup hash160 [8dc268a8e2876b941b95f3bd3b71050f003c5383] endif equalverify checksig"

HTLC Script

63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac

生成合约地址:

qx hash160 63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac | qx base58check-encode -v 0ee2

MEER HTLC Contract Address

TSPLoxLYMoAvkn2mqp27BW2aLmnk9n15L96

步骤 4 创建交易并广播

我们可以使用钱包直接转 10 个 MEER 到 TSPLoxLYMoAvkn2mqp27BW2aLmnk9n15L96 地址,也可以使用 qx 命令和kahf 工具创建交易,并广播;

获取UTXO

 ./kahf out -u TmbsdsjwzuGboFQ9GcKg6EUmrr3tokzozyF
1001d56dfbecb146aa8eb1c387d497ee5983bdb4dcea09649a267659ade2b284:2

使用 qx 命令创建交易:

qx tx-encode -i 1001d56dfbecb146aa8eb1c387d497ee5983bdb4dcea09649a267659ade2b284:2 -l 0 -o TmbsdsjwzuGboFQ9GcKg6EUmrr3tokzozyF:12.499 -o TSPLoxLYMoAvkn2mqp27BW2aLmnk9n15L96:10 | qx tx-sign -k <Alice private>
010000000184b2e2ad5976269a6409eadcb4bd8359ee97d487c3b18eaa46b1ecfb6dd5011002000000ffffffff02e0f57f4a000000001976a9148dc268a8e2876b941b95f3bd3b71050f003c538388ac00ca9a3b0000000017a914cc31cdfb555db880111cc7df793830bb7ecf6ce087000000000000000001000000000000000000000000000000006a47304402206d0b6c4671c2ce0db2efd619a0dc6e1fe56ea133ea7842dc7690f4d9a32dc05a0220335642c36009fe509d1462f06a69450e5c8df09a23b45d47df50a134a2847c1f01210354455a60d86273d322eebb913d87f428988ce97922a366f0a0867a426df78bc9

广播交易:

使用 qitmeer-cli 发送交易:

./qitmeer-cli sendRawTransaction 010000000184b2e2ad5976269a6409eadcb4bd8359ee97d487c3b18eaa46b1ecfb6dd5011002000000ffffffff02e0f57f4a000000001976a9148dc268a8e2876b941b95f3bd3b71050f003c538388ac00ca9a3b0000000017a914cc31cdfb555db880111cc7df793830bb7ecf6ce087000000000000000001000000000000000000000000000000006a47304402206d0b6c4671c2ce0db2efd619a0dc6e1fe56ea133ea7842dc7690f4d9a32dc05a0220335642c36009fe509d1462f06a69450e5c8df09a23b45d47df50a134a2847c1f01210354455a60d86273d322eebb913d87f428988ce97922a366f0a0867a426df78bc9
db0e8712b6bf1a0c7f746581abaa1566c8d090e5275837053c00909c8332ed23

步骤 5 Bob 创建 BTC 合约

Bob 创建使用 TSPLoxLYMoAvkn2mqp27BW2aLmnk9n15L96 合约中的脚本获取 Secret Key Hash 并创建镜像合约,用于获取 Secret Key。

bx script-decode 63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac
if ripemd160 [b75e2a5d3954e063a1de032caa7baed1029fa1e9] equalverify dup hash160 [cdd006e3adcd991a15f46c7e975686c1aec20773] else [005e445d] checklocktimeverify drop dup hash160 [8dc268a8e2876b941b95f3bd3b71050f003c5383] endif equalverify checksig

# Secret Key Hash b75e2a5d3954e063a1de032caa7baed1029fa1e9

BTC 合约:

OP_IF
    OP_RIPEMD160 
    # Secret Key Hash
    b75e2a5d3954e063a1de032caa7baed1029fa1e9 OP_EQUALVERIFY
    OP_DUP OP_HASH160 
    # Alice BTC PublicKeyHash
    843043481f636dafd10cb0433d4f34456eb3c840 
OP_ELSE
    # 2019.08.02 00:00:00
    800c435d  
    OP_CHECKLOCKTIMEVERIFY
    OP_DROP OP_DUP OP_HASH160 
    # Bob BTC PublicKeyHash
    46d96e0eb3f7de705b860347e451b9c41af72cd2 
OP_ENDIF OP_EQUALVERIFY OP_CHECKSIG

生成 BTC 合约地址:

bx script-encode "if ripemd160 [b75e2a5d3954e063a1de032caa7baed1029fa1e9] equalverify dup hash160 [843043481f636dafd10cb0433d4f34456eb3c840] else [800c435d] checklocktimeverify drop dup hash160 [46d96e0eb3f7de705b860347e451b9c41af72cd2] endif equalverify checksig" | bx bitcoin160 | bx base58check-encode -v 196

合约脚本:

63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914843043481f636dafd10cb0433d4f34456eb3c8406704800c435db17576a91446d96e0eb3f7de705b860347e451b9c41af72cd26888ac

合约地址

2MzaXi88QtpDLjxks4GEqfyZcfWybHbfAgc

使用钱包转入 0.001 BTC。

txid: 6c14149ee55a334262565333a2e4ef5779597dbc36f97c1e51657e01e70fe2f9

浏览器查询地址

步骤 6 Alice 赎回 BTC [原子交换]

Alice 使用 Secret Key 赎回 2MzaXi88QtpDLjxks4GEqfyZcfWybHbfAgc 的 BTC。

bx tx-encode -i 6c14149ee55a334262565333a2e4ef5779597dbc36f97c1e51657e01e70fe2f9:0 -o msZuJjb9m8pDMRNDRvaYCz9JcLTQt58RCZ:90000
0100000001f9e20fe7017e65511e7cf936bc7d597957efe4a23353566242335ae59e14146c0000000000ffffffff01905f0100000000001976a914843043481f636dafd10cb0433d4f34456eb3c84088ac00000000

签名交易:

bx input-sign <Alice private> "if ripemd160 [b75e2a5d3954e063a1de032caa7baed1029fa1e9] equalverify dup hash160 [843043481f636dafd10cb0433d4f34456eb3c840] else [800c435d] checklocktimeverify drop dup hash160 [46d96e0eb3f7de705b860347e451b9c41af72cd2] endif equalverify checksig" 0100000001f9e20fe7017e65511e7cf936bc7d597957efe4a23353566242335ae59e14146c0000000000ffffffff01905f0100000000001976a914843043481f636dafd10cb0433d4f34456eb3c84088ac00000000
304402206fb35f56b061f40b4ae92bef3e7e86c722e3cebf566b3fd3cb3c0c5ceee28d2902202032ee015f1a20ba21a38e6471336907a8210b15f87ed51f9e661dde55bc2b1f01

配置解锁脚本:

解锁脚本为

# < 签名 > < Alice publicKey > < Secret Key > OP_1 < contract script >
bx input-set "[304402206fb35f56b061f40b4ae92bef3e7e86c722e3cebf566b3fd3cb3c0c5ceee28d2902202032ee015f1a20ba21a38e6471336907a8210b15f87ed51f9e661dde55bc2b1f01] [0354455a60d86273d322eebb913d87f428988ce97922a366f0a0867a426df78bc9] [7bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa] 1 [63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914843043481f636dafd10cb0433d4f34456eb3c8406704800c435db17576a91446d96e0eb3f7de705b860347e451b9c41af72cd26888ac]"  0100000001f9e20fe7017e65511e7cf936bc7d597957efe4a23353566242335ae59e14146c0000000000ffffffff01905f0100000000001976a914843043481f636dafd10cb0433d4f34456eb3c84088ac00000000

0100000001f9e20fe7017e65511e7cf936bc7d597957efe4a23353566242335ae59e14146c00000000df47304402206fb35f56b061f40b4ae92bef3e7e86c722e3cebf566b3fd3cb3c0c5ceee28d2902202032ee015f1a20ba21a38e6471336907a8210b15f87ed51f9e661dde55bc2b1f01210354455a60d86273d322eebb913d87f428988ce97922a366f0a0867a426df78bc9207bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa514c5163a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914843043481f636dafd10cb0433d4f34456eb3c8406704800c435db17576a91446d96e0eb3f7de705b860347e451b9c41af72cd26888acffffffff01905f0100000000001976a914843043481f636dafd10cb0433d4f34456eb3c84088ac00000000

txid: db675bd88d8e67923954d2569aaf2468a56b594586239062eaa39bb5deca2b0a

浏览器查询地址

步骤 7 Bob 赎回 MEER [原子交换]

通过 BTC 交易 db675bd88d8e67923954d2569aaf2468a56b594586239062eaa39bb5deca2b0a Bob 可以在 scriptSig 字段中获得 Secret Key: 7bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa ,并从 TSPLoxLYMoAvkn2mqp27BW2aLmnk9n15L96 地址中取回 10 个 MEER。

MEER 赎回合约:

这里我们可以使用 qitmeer.js 库 来完成我们的交易。

const qitmeerJs = require('qitmeer.js')

function MeerUnit( num ) {
    return parseInt(num * 100000000)
}

function privateKeyToMeerP2PKH ( privateKeyBuffer ) {
    const keyPair = qitmeerJs.ec.fromPrivateKey(privateKeyBuffer)
    const hash160 = qitmeerJs.hash.hash160(keyPair.publicKey)
    const p2pkhAddress = qitmeerJs.address.toBase58Check(hash160, qitmeerJs.network.testnet.pubKeyHashAddrId)
    return {
        p2pkhAddress,
        keyPair
    }
}

function creatMEERP2SHTransaction({ privateKeyBuffer , amount, utxo, toAddress, contractScript,sigScript, lockTime, needsig } ) {
    const {p2pkhAddress, keyPair} = privateKeyToMeerP2PKH ( privateKeyBuffer )
    const publickey = keyPair.publicKey.toString('hex')
    const txb = qitmeerJs.txsign.newSigner(hlcnetwork);
    if (lockTime > 0) {
        txb.setLockTime(lockTime)
    }
    let amountAll = 0
    utxo.map( v => {
        const u = v.split(':')
        const inScript = {
            prevOutScript: qitmeerJs.script.fromBuffer(Buffer(contractScript+'','hex'))
        }
        if( lockTime > 0 ) inScript.sequence = 0
        amountAll += (u[2] || 0)*1
        txb.addInput( u[0], u[1]*1 ,inScript);
    })

    txb.addOutput( toAddress, MeerUnit( amount ));
    txb.addOutput( p2pkhAddress, MeerUnit( amountAll - amount - 0.0001 ));
    utxo.map( (v,i) => {
        txb.sign(i, keyPair);
        const transactionSign = txb.__inputs[i].signature.toString('hex');
        const s = (needsig?transactionSign.toString('hex') +' '+publickey+' ':'')+`${sigScript} ${contractScript}`
        txb.__tx.vin[i].script = qitmeerJs.script.fromAsm(s).toBuffer()
    })
    const newTransaction = txb.__tx.clone();
    return {
        Transaction: newTransaction.toBuffer().toString('hex'),
        RefundId: txb.getId()
    }
}

creatMEERP2SHTransaction ({
    privateKeyBuffer: Buffer('< Bob MEER privateKey >', 'hex') ,
    amount: 9.999,
    utxo: ['db0e8712b6bf1a0c7f746581abaa1566c8d090e5275837053c00909c8332ed23:1:10'],
    toAddress: 'TmhiKSDgr8SrGxEe7v6ee1TWY4FA6Nq5AQL',
    contractScript:'63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac',
    sigScript: '7bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa OP_1',
    lockTime: 0,
    needsig: true
})

010000000123ed32839c90003c05375827e590d0c86615aaab8165747f0c1abfb612870edb01000000ffffffff026043993b000000001976a914cdd006e3adcd991a15f46c7e975686c1aec2077388ac8f5f0100000000001976a914cdd006e3adcd991a15f46c7e975686c1aec2077388ac00000000000000000100000000000000000000000000000000e0483045022100a61dda54c0f40b2b92b47034032602d7b7f8ea962f5772d0f83fa0bb3182831b0220311affc73e953ee2573ae2964ce06f9f85d18376258180fe375a5b6f5eb85351012103136ed2c501056a6f8e6d57578e24d36ff1055c552ff0f8a28ba7bb284efeec2a207bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa514c5163a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac

广播交易

./qitmeer-cli sendRawTransaction 010000000123ed32839c90003c05375827e590d0c86615aaab8165747f0c1abfb612870edb01000000ffffffff026043993b000000001976a914cdd006e3adcd991a15f46c7e975686c1aec2077388ac8f5f0100000000001976a914cdd006e3adcd991a15f46c7e975686c1aec2077388ac00000000000000000100000000000000000000000000000000e0483045022100a61dda54c0f40b2b92b47034032602d7b7f8ea962f5772d0f83fa0bb3182831b0220311affc73e953ee2573ae2964ce06f9f85d18376258180fe375a5b6f5eb85351012103136ed2c501056a6f8e6d57578e24d36ff1055c552ff0f8a28ba7bb284efeec2a207bb05283f05a9b795bfbfd6a399b801ddf1fcd9e006a5ec24c9fa1cd826c8aaa514c5163a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac

txid: 6d5bdc381dfd9de4624f7d65a515cf2d5b5a6ce06458cbda4d867da7dae6837d

步骤 8 Bob 未按时完成交易时 Alice 取回 MEER

const qitmeerJs = require('qitmeer.js')

creatMEERP2SHTransaction ({
    privateKeyBuffer: Buffer('< Alice MEER privateKey >', 'hex') ,
    amount: 9.999,
    utxo: ['db0e8712b6bf1a0c7f746581abaa1566c8d090e5275837053c00909c8332ed23:1:10'],
    toAddress: 'TmbsdsjwzuGboFQ9GcKg6EUmrr3tokzozyF',
    contractScript:'63a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac',
    sigScript: 'OP_0',
    lockTime: 156467520,
    needsig: true
})

txid: "890f4563c329ef376e1ae78150ee280e7074375d1eeca93023761046e5221a9a"

raw:
"010000000123ed32839c90003c05375827e590d0c86615aaab8165747f0c1abfb612870edb0100000000000000026043993b000000001976a9148dc268a8e2876b941b95f3bd3b71050f003c538388ac8f5f0100000000001976a9148dc268a8e2876b941b95f3bd3b71050f003c538388ac40815309000000000100000000000000000000000000000000be473044022009233c04dd89097001b39959b52394165c34fd887c03b4bd1f06c356e676e6f802200b8ede3b95404c88361c2c3397673376fa5d9c38bba565e74c77c66f660df44b01210354455a60d86273d322eebb913d87f428988ce97922a366f0a0867a426df78bc9004c5163a614b75e2a5d3954e063a1de032caa7baed1029fa1e98876a914cdd006e3adcd991a15f46c7e975686c1aec207736704005e445db17576a9148dc268a8e2876b941b95f3bd3b71050f003c53836888ac"

至此我们完成了 BTC 和 MEER 的跨链操作。

当然,我们会将上述复杂的流程封装成客户端,方便普通用户使用,目前正在开发中。

下期内容:

实现 2 :MEER 和 USDT 原子互换

实现 3 :MEER 和 ETH 原子互换

实现 4 :MEER 和 ERC20Token 原子互换

原子交换技术实现第1期线上交流视频地址:腾讯视频

1 Like

干货, 有点难,

满满的干活,值得认真读读

满满的干活

:100: