文章目录

  • jiaoyi的创建与验证
    • 练习1
      • 代码实现
      • 对上述函数代码的解释
    • 练习2
      • 代码实现
      • 对上述函数代码的解释
    • 练习3
      • 代码实现
      • 对上述函数代码的解释
    • 练习4
      • 代码实现
      • 运行结果
    • 看一下发布后的样子
    • 练习5
      • 代码实现
      • 运行结果
    • 看一下发布后的样子

《区块链编程》第七章

jiaoyi的创建与验证

审核不通过,提示违法违规, 尝试一下是否是jy两个字的原因

练习1

p129

代码实现

# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date:   2022-01-09 18:28:43
# @Last Modified by:   从化北
# @Last Modified time: 2022-01-09 18:53:24class Tx:
...
def sig_hash(self, input_index):'''Returns the integer representation of the hash that needs to getsigned for index input_index'''# start the serialization with version# use int_to_little_endian in 4 bytess = int_to_little_endian(self.version, 4)# add how many inputs there are using encode_varints += encode_varint(len(self.tx_ins))# loop through each input using enumerate, so we have the input indexfor i, tx_in in enumerate(self.tx_ins):# if the input index is the one we're signingif i == input_index:# Only the signature script of the specified input is replaced,# and the signature scripts of other inputs are empty.# the previous tx's ScriptPubkey is the ScriptSig# Otherwise, the ScriptSig is empty# add the serialization of the input with the ScriptSig we wants += TxIn(prev_tx=tx_in.prev_tx,prev_index=tx_in.prev_index,script_sig=tx_in.script_pubkey(self.testnet),sequence=tx_in.sequence,).serialize()else:s += TxIn(prev_tx=tx_in.prev_tx,prev_index=tx_in.prev_index,sequence=tx_in.sequence,).serialize()# add how many outputs there are using encode_varints += encode_varint(len(self.tx_outs))# add the serialization of each outputfor tx_out in self.tx_outs:s += tx_out.serialize()# add the locktime using int_to_little_endian in 4 bytess += int_to_little_endian(self.locktime, 4)# add SIGHASH_ALL using int_to_little_endian in 4 bytess += int_to_little_endian(SIGHASH_ALL, 4)# hash256 the serializationh256 = hash256(s)# convert the result to an integer using int.from_bytes(x, 'big')return int.from_bytes(h256, 'big')

对上述函数代码的解释

对sig_hash函数的解释:输入:交易中input的索引输出:z(签名哈希)内部执行逻辑:首先说明一个前提: 每一个input对应一个z,(换句话说,每一个签名脚本对应一个z)求当前input的z,将该input的签名脚本更换为其父交易output中的公钥脚本。(p126)其他各部分均不变。而后对更改后的交易,进行hash256,转换为大端序的int值,即为当前input的z。

练习2

p129

代码实现

# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date:   2022-01-09 18:53:45
# @Last Modified by:   从化北
# @Last Modified time: 2022-01-09 18:58:41class Tx:
...
def verify_input(self, input_index):'''Returns whether the input has a valid signature'''# get the relevant inputtx_in = self.tx_ins[input_index]# grab the previous ScriptPubKeyscript_pubkey = tx_in.script_pubkey(testnet=self.testnet)# get the signature hash (z)z = self.sig_hash(input_index)# combine the current ScriptSig and the previous ScriptPubKeycombined = tx_in.script_sig + script_pubkey# evaluate the combined scriptreturn combined.evaluate(z)

对上述函数代码的解释

对verify_input函数的解释:输入:交易中input的索引输出:True/False函数要做的事情:验证input是否有效验证逻辑:验证input有效,就是验证Script对象运行结果非0。一个Script对象的组成:当前input的签名脚本当前input父交易的公钥脚本而Script对象需要z来验证。具体深入请看Script章节以及椭圆曲线密码学数字签名算法部分

练习3

p134

代码实现

# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date:   2022-01-09 19:35:33
# @Last Modified by:   从化北
# @Last Modified time: 2022-01-09 19:35:33class Tx:
...def sign_input(self, input_index, private_key):# get the signature hash (z)z = self.sig_hash(input_index)# get der signature of z from private keyder = private_key.sign(z).der()# append the SIGHASH_ALL to der (use SIGHASH_ALL.to_bytes(1, 'big'))sig = der + SIGHASH_ALL.to_bytes(1, 'big')# calculate the secsec = private_key.point.sec()# initialize a new script with [sig, sec] as the cmds# change input's script_sig to new scriptself.tx_ins[input_index].script_sig = Script([sig, sec])# return whether sig is valid using self.verify_inputreturn self.verify_input(input_index)

对上述函数代码的解释

对sign_input函数的解释:输入:交易中input的索引私钥输出:输出input签名脚本的验证结果( True / False)函数要做的事情:填充某一input的签名脚本验证input签名是否有效p2pk标准脚本的脚本签名包括两个元素:sig = der + 签名授权哈希sec

练习4

p135

代码实现

# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date:   2022-01-09 21:58:03
# @Last Modified by:   从化北
# @Last Modified time: 2022-01-10 16:21:53
from ecc import PrivateKey
from helper import decode_base58, SIGHASH_ALL, little_endian_to_int, hash256
from script import p2pkh_script, Script
from tx import TxIn, TxOut, Tx# 父交易ID,现在申请的,里面有0.001=十万聪
prev_tx = bytes.fromhex('941999e918522d1d9c4691ab67dcd0effe22ed3a5664ab93f397fe865c600553')
# 父交易的序号
prev_index = 0
# 目标地址,(donate address)
target_address = '37NFX8KWAQbaodUG6pE1hNUH1dXgkpzbyZ'
# 金额
target_mount = 0.00006
# 剩于部分发送的地址,另一个新建的地址,第三个
change_address = 'mosFzEQBzLyMgEPGu9LXoaB4iDjo4okffL'
# 向“剩余地址”发送的金额,其他作为手续费
change_mount = 0.0008
# 秘钥
secret = b"***********"
secret = little_endian_to_int(hash256(secret))
# 由秘钥创建的私钥
priv = PrivateKey(secret=secret)
# 构建input
tx_ins = []
# 添加input
tx_ins.append(TxIn(prev_tx, prev_index))
# 构建output
tx_outs = []
# 将目的地址的base58形式解析出哈希地址
h160 = decode_base58(target_address)
# 构建交易的公钥脚本
script_pubkey = p2pkh_script(h160)
# 交易以聪为单位,1 比特币 = 1亿 聪
target_satoshis = int(target_mount * 100000000)
# 构建并添加output
tx_outs.append(TxOut(target_satoshis, script_pubkey))
# 将“剩余地址”的base58形式解析出哈希地址
h160 = decode_base58(change_address)
# 构建交易的公钥脚本
script_pubkey = p2pkh_script(h160)
# 交易以聪为单位,1 比特币 = 1亿 聪
change_satoshis = int(change_mount * 100000000)
# 构建并添加output
tx_outs.append(TxOut(change_satoshis, script_pubkey))
# 构建交易
tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
# 校验签名可用
print(tx_obj.sign_input(0, priv))
# 打印交易的完整hex
print(tx_obj.serialize().hex())# 广播交易的网站
# https://live.blockcypher.com/btc/pushtx

运行结果

补充说明, 这个交易已经被我发布了.
广播交易的一个网站

True
01000000015305605c86fe97f393ab64563aed22feefd0dc67ab91469c1d2d5218e9991994000000006a473044022100f34a7dbbaa83de7e064c1ce5664ac80eb6c201538eafd4fe94a453432ac2b8c8021f5037b3d9fc4f60bc9879bcd8fcd5a711885892989b475033f48c2c6112273701210284bfcdd7f8d2cc4732cabc508c7f309b5ac5705698a8753a183ddff550e2d153ffffffff0270170000000000001976a9143e443375e10eef0236cdb243bdec473918c9a1dd88ac80380100000000001976a9145b98183ab5ffaeee7d03f3a58da039db9b88cd9a88ac00000000
[Finished in 1.5s]

看一下发布后的样子

  1. 一个input 两个output
  2. 广播交易的网站之一(这个突然挂掉了,下面test05,使用了另一个广播交易的网站)
  3. tx_id : 941999e918522d1d9c4691ab67dcd0effe22ed3a5664ab93f397fe865c600553
  4. 感兴趣大家可以自己查一下这个交易链接,这里给出另一个区块链浏览器

练习5

p135

代码实现

# -*- coding: utf-8 -*-
# @Author: 从化北(喵星人)
# @Date:   2022-01-10 16:28:04
# @Last Modified by:   从化北
# @Last Modified time: 2022-01-10 18:03:42
from ecc import PrivateKey
from helper import decode_base58, SIGHASH_ALL, little_endian_to_int, hash256
from script import p2pkh_script, Script
from tx import TxIn, TxOut, Tx# 1 btc = 1亿 聪
RATE = 100000000
# 父交易1的ID;上一个找零交易, 0.0008 btc
prev_tx_1 = bytes.fromhex('50bf400cfbd2669434be467e9e277e1db88610f0ef2f8ec5a1631f0bf9f5ae78')
# 父交易1的序号
prev_index_1 = 1
# 父交易2的ID,水龙头交易;0.0001 btc
prev_tx_2 = bytes.fromhex('019ea8b778aac75b6b344e69912a5a98927bcefccaaf366f84e31ddc74668407')
# 父交易1的序号
prev_index_2 = 0
# 一共0.0009 btc
# 目标地址1,自己的一个地址
target_address = 'mvgTF5toE4Y7d59ibvq5E7fMka7uiAYprs'
target_mount = 0.00006
# 剩于部分发送的地址,自己的另一个地址
# https://bitcoinfaucet.uo1.net/send.php
denote_address = 'mh7ymnwwfG22BcdLmYf5cnHYLjjXpEFbcj'
# 向“剩余地址”发送的金额,留出0.001作为手续费
denote_mount = 0.00002
# 秘钥数字, 花钱
secret = b"******************"
secret = little_endian_to_int(hash256(secret))
# 由秘钥创建的私钥
priv = PrivateKey(secret=secret)
# 构建input
tx_ins = []
# 添加两个input
tx_ins.append(TxIn(prev_tx_1, prev_index_1))
tx_ins.append(TxIn(prev_tx_2, prev_index_2))
# 构建output
tx_outs = []
# 将目的地址的base58形式解析出哈希地址
h160_1 = decode_base58(target_address)
h160_2 = decode_base58(denote_address)# 构建交易的公钥脚本
script_pubkey_1 = p2pkh_script(h160_1)
script_pubkey_2 = p2pkh_script(h160_2)
# print(script_pubkey)
# 交易以聪为单位,1 比特币 = 1亿 聪
target_satoshis = int(target_mount * RATE)
decote_satoshis = int(denote_mount * RATE)
# 构建并添加output
tx_outs.append(TxOut(target_satoshis, script_pubkey_1))
tx_outs.append(TxOut(target_satoshis, script_pubkey_2))
# 构建交易
tx_obj = Tx(1, tx_ins, tx_outs, 0, testnet=True)
print(tx_obj.fee())
# 校验签名可用
print(tx_obj.sign_input(0, priv))
print(tx_obj.sign_input(1, priv))
# 打印交易的完整hex
print(tx_obj.serialize().hex())

运行结果

补充说明, 这个交易已经被我发布了.
广播交易的一个另一个网站,之前那个不知怎么,暂时挂掉了

True
True
010000000278aef5f90b1f63a1c58e2feff01086b81d7e279e7e46be349466d2fb0c40bf50010000006b48304502210089c548abd0e736c66dcb3f80a91457316b8b38c35e28dab6e80c689d90795d9102206ce6a37dbc709eed10552ba21504ac31dc5672277204cc6ee90eae9c64234fcb012102fbb36a53ef74d0ed81e114fc5e47624d8f9e4d329983db90020b3dbbcd25a21cffffffff07846674dc1de3846f36afcafcce7b92985a2a91694e346b5bc7aa78b7a89e01000000006b483045022100a094452d4475dd0dc74f212ab259761f32c04b6ef9ef276461d4d6926603cf7a02201638858c428f79f0bb0ec48bd101353c238528b8c7ddb997f64f1d5f4e71be21012102fbb36a53ef74d0ed81e114fc5e47624d8f9e4d329983db90020b3dbbcd25a21cffffffff0270170000000000001976a914a655cbb0b31bcd08157a6aeecc5d76a2e5be2bbe88ac70170000000000001976a9141197eb1e848ae52638df6bf205ffd9dd2d93c26788ac00000000
[Finished in 2.2s]

看一下发布后的样子

两个input 两个output
tx_id : 5e33aadfa079c3dac8176203ab5644a75d2129cf98f4085499b52887e73c2543
感兴趣大家可以自己查一下这个交易链接,这里给出另一个区块链浏览器

《区块链编程》第七章相关推荐

  1. 计算机软件行业大部分成本是,平狄克微观经济学第七章成本问题

    <平狄克微观经济学第七章成本问题>由会员分享,可在线阅读,更多相关<平狄克微观经济学第七章成本问题(45页珍藏版)>请在人人文库网上搜索. 1.第七章 成本问题,目录,成本的测 ...

  2. 《微观经济学》 第七章

    第七章 不完全竞争市场中的厂商行为 7.1 垄断的成因 竞争和垄断以不同的比例存在于各个市场中,把这个比例叫做市场结构. 在不同的市场结构下,厂商的决策模式是有很大差异的. 完全竞争.垄断竞争.寡头垄 ...

  3. 数字图像处理——第七章 小波和多分辨处理

    数字图像处理--第七章 小波和多分辨率处理 文章目录 数字图像处理--第七章 小波和多分辨率处理 写在前面 1 多分辨率处理 1.1 图像金字塔 1.2 多尺度和多分辨率的区别 2 小波 2.1 连续 ...

  4. 现实迷途 第七章 特殊客户

    第七章 特殊客户 注:原创作品,请尊重原作者,未经同意,请勿转载,否则追究责任. 江北一般都是上午待在办公室里,搜集信息或整理以前做过的系统,下午才出去站街招客. 站街站了一段时间后,江北有点不想去了 ...

  5. stm32 工业按键检测_「正点原子STM32Mini板资料连载」第七章 按键输入实验

    1)实验平台:正点原子STM32mini开发板 2)摘自<正点原子STM32 不完全手册(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第七章 按键输入实验 上一章,我们介 ...

  6. 第七章——DMVs和DMFs(2)——用DMV和DMF监控索引性能

    原文: 第七章--DMVs和DMFs(2)--用DMV和DMF监控索引性能 本文继续介绍使用DMO来监控,这次讲述的是监控索引性能.索引是提高查询性能的关键性手段.即使你的表上有合适的索引,你也要时时 ...

  7. 2017上半年软考 第七章 重要知识点

    第七章项目范围管理 []项目范围管理概念 [][]项目范围管理的含义和作用 项目范围管理内容p289 项目范围对项目管理的重要性?p289 [][]项目范围管理的主要过程 项目范围管理的6个过程是? ...

  8. 服务器架构之性能扩展-第七章(8)

    第七章Cacti系统监控邮件报警和压力测试 7.1 Cacti工作原理 原理简单来说,Cacti就是rrdtool的一个forefront,它内置了快速的获数据取工具.优秀的绘图模板以及许多设计精良的 ...

  9. 鸟哥Linux私房菜_基础篇(第二版)_第七章学习笔记

    第七章 Linux文件和目录管理 绝对路径:以"/"开始 相对路径:以非"/"开始 其中,"."代表当前目录,".."代 ...

  10. 计算机组成原理 输入输出系统,计算机组成原理(第七章输入输出系统

    计算机组成原理(第七章输入输出系统 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 第七章输入输出系统第一节基本的输入输出方式一. 外围 ...

最新文章

  1. 通信系统中对眼图的理解(一)
  2. win11什么时候发布的_2021年初级会计师考试大纲什么时候发布?
  3. 如何查看数据库索引的利用率?
  4. Visual Studio 2010 重构XAML的一个bug
  5. Actor模型(分布式编程)
  6. OkHttp 3.x 源码解析之Interceptor 拦截器
  7. python数据结构与算法第六讲_Python 学习 -- 数据结构与算法 (六)
  8. python切换消息窗_用Python切换窗口
  9. 《Head First设计模式》第六章笔记-命令模式
  10. Oracle安装步骤(自用)
  11. 人脸识别系统Python源代码的实现
  12. python制作自动交易软件-Python语言之一位程序员写了一个自动化交易程序,躺着玩,两年就挣了两百万!...
  13. Excel·VBA考勤打卡记录数据整理
  14. 【C语言】乘法口诀表
  15. 《CSS权威指南》读书笔记4
  16. asp微信点餐系统源码,asp扫码点餐代码,支持连接飞鹅云打印机
  17. Tomcat服务器配置https双向认证,使用JDK的keytool生成证书(适用于web、安卓、IOS)
  18. Mock服务(1)---- 初识Mock
  19. Python与企业微信-2
  20. SpringCloud读取Nacos配置中心报错:Could not resolve placeholder ‘xxx’ in value ‘${xxx}

热门文章

  1. css实现两端对齐的方法(先借鉴别人的,后期再加入自己的理解)
  2. 基因重组-冲刺日志(第五天)
  3. 基于龙芯CPU中标麒麟操作系统的国产半实物仿真系统ETestDEV
  4. 什么是浏览器?2、常见的主流浏览器及其内核?什么是服务器?(学习笔记)
  5. 腾讯发布三项息争前提 360将扣扣保镖下线
  6. ipadpro尺寸的html,iPad Pro屏幕尺寸是多少?iPad Pro分辨率是多少?
  7. iPad的屏幕大小是多少?
  8. 股市实时行情分发工具-拿来就用
  9. Kafka报错: Topic(s) [publish] is/are not present and missingTopicsFatal is true
  10. win7 pptp服务器未响应,win7下vpn无法使用的解决办法