区块链第四次作业跨链原子交换交易

实验介绍与要求

要求:

在本次任务中,你需要创建一个称为跨链原子交换的交易,允许两个实体在不同的区块链上安全地交换加密货币的所有权。

介绍

在这项作业中,你需要实现Alice和Bob两方之间跨链原子交换代码的关键部分。Alice在BTCTestnet3上有比特币,这是project1使用的标准比特币测试网。Bob在BCY Testnet 上拥有比特币,BCY Testnet是Blockcypher 的比特币测试网,由Blockcypher独家挖矿和维护。他们希望安全地交换各自coin的所有权,这是一个简单交易无法完成的事情,因为它们位于不同的区块链上。这里的想法是围绕一个只有一方(Alice)知道的秘密x建立交易。在这些事务中,只有H(x)将被发布,而x为秘密。交易将以这样的方式建立,一旦x被揭露,双方都可以赎回对方发送的硬币。如果x永远不会被揭露,双方将能够安全地取回他们的原始硬币,而不需要另一方的帮助。这种方法也适用于其他加密货币。

实验过程

配置环境

运行课程代码pip install -r requirements.txt安装所需的依赖项。确保使用的是python3。

这个之前已经已经接安装过了这次就不用再做了

创建BTC密钥并领取测试币

(a)为Alice和 Bob 创建BTC testnet密钥。你可以用keygen.py 生成密钥,把它填入keys.py中合适的地方。
(b)在 Project1中相同的coinfaucet 上,为Alice的BTC地址领取测试币。

这个也是之前做过的了,慢慢找公交车人行道自行车吧,Good Luck!

注册BCY创建密钥领取测试币

(a)在Blockcypher注册帐户以获取API token: https://accounts.blockcypher.com/。
(b)为Alice和Bob创建BCY testnet密钥并填入keys.py.

curl-X POST https://api.blockcypher.com/v1/bcy/test/addrs?token=YOURTOKEN

(c)在Blockcypher 测试网(BCY)上为Bob的BCY地址领取测试币。

curl-d'{"address":"BOB_BCY_ADDRESs", "amount": 1000000}' https://api.blockcypher.com/v1/bcy/test/faucet?token=YOURTOKEN

这个相对于BTC领币过程也太“流云行水”了,curl用前需要装一下,终端输入sudo apt-get install curl就能装了。然后在终端里输入题目里给的命令就好

划分测试币

使用split_test_coins.py(填写文件中的相关字段)划分领取的币。

把对应的地方填上就行,不过需要注意,划分BCY测试币的时候,注意改一下调用的函数(参考keys.py中的样式),以及network的类型

#BTC:
my_private_key = CBitcoinSecret('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
#BCY:
my_private_key = CBitcoinSecret.from_secret_bytes(x('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'))


完善swap.py

填写swap.py.

按照提示一步一步写

完善swap_scripts.py

这部分是本次实验核心部分

要求及源码

A.考虑创建跨链原子交换所需事务所需的ScriptPubKey。此交易必须可由接收者赎回(如果他们有一个与Hash(x)对应的秘密x),或者可以用发送者和接收者的两个签名赎回。完善swap_scripts.py 中的脚本coinExchangeScript。
B.完善脚本:
(a)在接收者知道秘密x的情况下,编写赎回交易所需的ScriptSig。在swap_scripts.py中完善coinExchangeScriptSig1.
(b)在发送方和接收方都签署事务的情况下,编写赎回事务所需的ScriptSig。在swap_scripts.py中完善coinExchangeScriptSig2.

def coinExchangeScript(public_key_sender, public_key_recipient, hash_of_secret):
    return [
        # fill this in!
    ]
def coinExchangeScriptSig1(sig_recipient, secret):
    return [
        # fill this in!
    ]
def coinExchangeScriptSig2(sig_sender, sig_recipient):
    return [
        # fill this in!
    ]

思路

根据题目要求,我们的锁定脚本应该能够用两个不同解锁脚本解锁所以需要用到OP_IFOP_ELSEOP_ENDIF等脚本语言来处理不同解锁脚本。

  • 对于用秘密X及接收者签名赎回的脚本,我们只需要先验证X的哈希值是否正确,然后再用P2PK脚本验证接收者签名
  • 对于用两个签名赎回的脚本,我们只需要用P2MS就可以实现
  • 对于知道秘密X的解锁脚本,我们只需将签名与秘密依次压栈
  • 对于两个签名的解锁脚本,把两个签名压栈即可,不过需要注意先OP_0

实现

解锁脚本1:
<sig_recipient>,<seret>
解锁脚本2:
OP_0 <sig_sender> ,<sig_recipient>
锁定脚本:
OP_DEPTH, 2, OP_EQUAL, 
OP_IF, 
OP_HASH160, hash_of_secret, OP_EQUALVERIFY, public_key_recipient, OP_CHECKSIG, OP_ELSE,
2, public_key_sender, public_key_recipient, 2, OP_CHECKMULTISIG,
OP_ENDIF
解释:

可以把锁定脚本看作三部分

  • 第一部分是用来检验是哪个解锁脚本从而执行相应的检验
    我们可以发现两个脚本长度不同,于是可以利用这一点来分辨是哪个脚本,利用OP_DEPTH得到栈大小可以实现
    或者是在第二个解锁脚本中存在一个OP_O,于是可以用OP_PICK将栈底复制到栈顶,然后与OP_0对比,这样也可以
  • 第二部分是执行OP_IF后的分支,验证秘密X与接收者签名
  • 第三部分是执行OP_ELSE后的分至,验证两个签名
执行过程

对于解锁脚本1+锁定脚本

NULL							|初始状态栈为空
<sig_recipient><seret>		  |<sig_recipient>,<seret>依次入栈
<sig_recipient><seret><2>	   |OP_DEPTH得到栈大小为2,并将2压栈
<sig_recipient><seret><2><2>	|2入栈
<sig_recipient><seret><Ture>	|OP_EQUAL比较栈顶两个的值并将其pop,将Ture压栈,这里不能用OP_EQUALVERIFY,因为我们需要在栈里压入一个标志来确定执行OP_IF还是OP_ELSE
<sig_recipient><seret>		  |OP_IF检测栈顶值并将其pop,进入if分支
<sig_recipient><hash_of_secret?>|得到secret的哈希值
<sig_recipient><hash_of_secret?><hash_of_secret>|<hash_of_secret>压栈
<sig_recipient>		   	  |OP_EQUALVERIFY检测两个哈希值是否相等并将其pop
<sig_recipient><public_key_recipient>|public_key_recipient入栈
<Ture>						  |OP_CHECKSIG
<Ture>						  |最后几步其实就是简单的P2PK,最后的OP_ENDIF一定要加			

对于解锁脚本1+锁定脚本

NULL 							           |初始状态栈为空
<OP_0><sig_recipient><sig_recipient>       |<OP_0><sig_recipient><sig_recipient>依次入栈
<OP_0><sig_recipient><sig_recipient><3>    |OP_DEPTH得到栈大小为,并将3压栈
<OP_0><sig_recipient><sig_recipient><3><2> |2入栈
<OP_0><sig_recipient><sig_recipient><False>|OP_EQUAL比较栈顶两个的值并将其pop,将False压栈
<OP_0><sig_recipient><sig_recipient>	   |OP_IF检测栈顶值,为false,不执行if分至,有OP_ELSE,跳转到else
#略

省略的部分其实就是P2MS的过程,详情可见我之前的博客


2020/11/28 0:09:58

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值