Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

比特币交易构成(二)

梦的衣裳323
277 0 0
交易的构造、签名与广播
$ u8 z. T2 s* W, F9 L% J$ H上篇介绍了交易结构、签名等,为了更直观的认识比特币,借助bitcoind演示手动构造并广播交易的完整过程。2 h- d* G3 {) b' O
普通交易6 ~1 I" w9 A% [5 b
1. 找出未花费的币(unspent output)
/ f" i* u" T4 y. q' T1 V! a" Y通过命令:listunspent [minconf=1] [maxconf=9999999] ["address",...]列出某个地址未花费的币(交易),minconf/maxconf表示该笔收入交易的确认数范围,如果需要列出还未确认的交易,需将minconf设置为0。/ l. V- a% [! X* \' J  r7 `- g
执行:
) f9 J9 i4 d& L1 j( z2 Kbitcoind listunspent 0 100 '["1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"]'
- p2 O4 W! x& N输出:& a1 g. g, k8 F9 A5 j, g$ {
[! p- p3 @9 y- n* V. N4 z
    {( i" k) b/ E/ Q* u& X9 I9 {
        "txid" : "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",
! F& k8 d3 y- n. z" ]: L        "vout" : 0,' z/ }! ?2 \" Y+ w
        "address" : "1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3",
) h; O$ t4 _  a; K- Q/ C5 f, ?        "account" : "",0 s4 z4 i9 x; ~' h
        "scriptPubKey" : "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac"," r) H2 t! W5 J* ^) N; S5 f
        "amount" : 0.19900000,
5 m! Q& ^' t) d        "confirmations" : 1
+ n. D7 @3 N) v; b+ Y    }# U- M1 h, C) H% [1 \" C
]
' Y6 h8 C# }0 h我们找到该地址的一个未花费交易,位于交易296ea7bf981b4499…9f0a41e589132156的第0个位置。5 [7 S" z$ g: \/ ^* ?% y) W5 \$ B
2. 创建待发送交易4 E6 m1 L% q4 c" L- N
创建待发送交易,由命令:createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...}来完成。我们将 0.1 BTC发送至 1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x ,并支付 0.0001 BTC做为矿工费。输入交易的额度为 0.199 ,输出为 0.1 + 0.0001 = 0.1001 ,那么还剩余: 0.199 - 0.1001 = 0.0989 ,将此作为找零发回给自己。
+ {5 c. P( j; S! b) b2 E执行:
' _5 V& ?' _8 Y9 P! @  i3 ubitcoind createrawtransaction \% C) ]! x6 |* m+ }- J
'[{"txid":"296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156","vout":0}]' \$ {0 e# N9 C, l, H' d! S# @
'{"1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x":0.1, "1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3":0.0989}'
& N. b: s5 P7 g; D# _8 O1 H输出:
( n& V/ h5 v5 l- Y' r& l010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000- L) c  V. w) W: N
通过命令:decoderawtransaction ,可以将此段十六进制字符串解码。9 G: Q, b8 l+ k4 }/ |- U/ I
执行:2 N& _& p% v* f# X8 v
bitcoind decoderawtransaction '010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000'
1 B( F; [; _& Y9 d( K输出:9 a' `' C  |. W  f" B! G# h9 O
{4 w5 ^# }" N5 y! }: t8 F  l9 _
    "txid" : "54f773a3fdf7cb3292fc76b46c97e536348b3a0715886dbfd2f60e115fb3a8f0",
- [3 q- v) Q& A# A0 L! a    "version" : 1,
4 J5 w" G! r" P. u    "locktime" : 0,
8 f( }  X: t! d; [    "vin" : [
: _. Z1 x/ V% Z5 d        {
; n7 G% J: B: M4 ^- ?* ?5 r            "txid" : "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",$ d+ t5 B9 P% t
            "vout" : 0,% O% I( T4 r6 T0 X
            "scriptSig" : {3 B; r, l9 i* y) n
                "asm" : "",7 O$ Q8 |" ~) f$ c$ X0 i% k, W
                "hex" : ""
5 h* G* Q" B% j7 K            },4 r+ x6 T% a  H% _) \- x
            "sequence" : 4294967295. Z5 W' |9 @: x/ B
        }- Q7 Z% y$ }/ [0 U
    ],5 P, u0 F& G6 u* _6 R" T5 D3 c
    "vout" : [
1 x6 V; V* i) h$ O: T        {
. L( W( z' T; t, {            "value" : 0.10000000,
! t/ P' x0 t. W% H" {8 B            "n" : 0,
6 w+ z2 O3 v& p            "scriptPubKey" : {
  p4 T0 J. `( P+ @7 U                "asm" : "OP_DUP OP_HASH160 fdc7990956642433ea75cabdcc0a9447c5d2b4ee OP_EQUALVERIFY OP_CHECKSIG",
! x3 o8 }5 h; k* K7 G, w                "hex" : "76a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88ac",
* J8 D% ~4 x1 S1 B$ x; U% O1 o                "reqSigs" : 1,
) k8 X' t. O! S                "type" : "pubkeyhash",: o: U9 h' o; ?6 R- t3 s
                "addresses" : [
7 p) i" \7 Y# G4 E# p- Q. M; E                    "1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x"# h5 B4 V. N/ [1 D
                ]
7 _! u$ Z$ o6 q, s5 U            }
5 ?1 z; M  u6 a& Y) u        },
7 L& I% H0 u, T& o1 A        {
, b0 G2 w3 {# o5 D6 _9 T7 R$ U( V            "value" : 0.09890000,7 W/ u* \+ a' R
            "n" : 1,% E' s  `7 u3 F' U2 l
            "scriptPubKey" : {
- }' S5 H; D" P                "asm" : "OP_DUP OP_HASH160 d6c492056f3f99692b56967a42b8ad44ce76b67a OP_EQUALVERIFY OP_CHECKSIG",/ H" U) o/ y( q* s" a
                "hex" : "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
6 i( _( Y# P2 B" u/ e+ z$ {                "reqSigs" : 1,) w- ^) `7 T% M6 t6 G  p5 M+ N2 s
                "type" : "pubkeyhash",
8 I: j- q2 M* _                "addresses" : [
+ L& W0 f0 m& |* V+ m5 K. U                    "1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"' I. {% r9 O0 @
                ]
* A5 C2 Y% }) _            }* u" L% B3 m% E& S5 R& c4 T
        }# z$ S7 v8 I' b1 z" j
    ]/ e+ a+ j5 N* Z8 a
}, Q3 W) W! E8 V+ S0 U
至此,一个“空白交易”就构造好了,尚未使用私钥对交易进行签名,字段scriptSig是留空的,无签名的交易是无效的。此时的Tx ID并不是最终的Tx ID,填入签名后Tx ID会发生变化。
% ^: T/ t  z) d: y在手动创建交易时,务必注意输入、输出的值,非常容易犯错的是忘记构造找零输出(如非必要勿手动构造交易)。曾经有人构造交易时忘记找零,发生了支付 200 BTC 的矿工费的人间惨剧,所幸的是收录该笔交易的Block由著名挖矿团队“烤猫(Friedcat)”挖得,该团队非常厚道的退回了多余费用。
7 u. ?4 O) g5 p" |* d, _3. 签名
" U6 N0 L8 I" H; F交易签名使用命令:
0 [$ ]* F* V0 jsignrawtransaction  \
, }. k" |- |8 B- H- @( X3 F5 j[{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [,...] \
. {" Q: @0 {+ Y5 ~' r% w+ e& K[sighashtype="ALL"]
( h( ^1 p0 z( w0 j' A第一个参数是创建的待签名交易的十六进制字符串;第二个参数有点类似创建交易时的参数,不过需要多出一个公钥字段scriptPubKey,其他节点验证交易时是通过公钥和签名来完成的,所以要提供公钥;如果是合成地址,则需要提供redeemScript;0 T8 C+ M: c, E* {  A" ?% K
第三个参数是即将花费的币所在地址的私钥,用来对交易进行签名,如果该地址私钥已经导入至bitcoind中,则无需显式提供;
最后一个参数表示签名类型,在上一篇里,介绍了三种交易签名类型;
" {- K: a6 B( f
6 K1 o0 I' _, B* W; e
签名之前需要找到scriptPubKey,提取输入交易信息即可获取(也可以根据其公钥自行计算),由命令:getrawtransaction  [verbose=0]完成。
' L6 f/ @8 R/ `执行:
# R9 [2 @7 U3 n9 W% _, o% E6 Ybitcoind getrawtransaction 296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156 18 U5 a& E$ J2 f
输出:9 ~7 D$ Z" q$ e- ~$ g; I% d$ c
{
. `+ h" u( J+ t% e    "hex" : "01000000010511331f639e974283d3909496787a660583dc88f41598d177e225b5f352314a000000006c493046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d4012103cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4ffffffff0160a62f01000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000",8 B4 ]5 C0 |* a! W3 G, f) |- `$ }
    "txid" : "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",
9 M- q4 v3 u" D8 n1 K    "version" : 1,5 a8 ?0 w; Y4 O) V8 t! J6 O
    "locktime" : 0,3 }! |  z2 `* r- s# h+ l
    "vin" : [/ }1 Y2 O9 U( N* U( R8 |3 V; E+ K
        {
7 z* L  c6 k: E" j            "txid" : "4a3152f3b525e277d19815f488dc8305667a78969490d38342979e631f331105",
) L& m# m6 h0 D            "vout" : 0,
& F: u7 B' h, a5 [9 S3 v$ p2 m            "scriptSig" : {
/ b4 p( e. B: b                "asm" : "3046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d401 03cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4",! `0 R% b2 e  L2 ~1 r; ^3 t
                "hex" : "493046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d4012103cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4"
2 ~' X7 h! R+ K( [& B            },/ O+ x. N; q+ }( I( |
            "sequence" : 42949672958 ^* s  \5 d' T# L# ?" z  I
        }; y7 w  d# [" g$ b% _  F
    ],
5 C; f2 F8 u- k0 }+ Q9 }. y) x6 A    "vout" : [
5 R2 a7 R  s* W7 X- P2 N! q: N        {! x" C. N# }1 s' N& G* \- X
            "value" : 0.19900000,
# a0 q% Q% b& m$ E            "n" : 0,
1 j# ?# S& M! e# |            "scriptPubKey" : {
; a& |- f" Z* K9 }* U7 g  K4 U+ q                "asm" : "OP_DUP OP_HASH160 d6c492056f3f99692b56967a42b8ad44ce76b67a OP_EQUALVERIFY OP_CHECKSIG"," P% f- `5 Z2 M
                "hex" : "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
6 ]0 N( B5 c6 N: h* H: q6 N                "reqSigs" : 1,
1 @+ K. I" ~& A- s6 A- f5 ]                "type" : "pubkeyhash",
2 O0 \4 f+ p5 O0 {, m                "addresses" : [
' d" @$ C3 d4 N" w+ o2 e6 H9 ]0 {                    "1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"+ G8 E1 R, |- S' m% u; r
                ]
  [' c5 R1 ~% o+ t) _            }
8 ?; U  |# a: V        }
/ V1 p( W+ ]) K: o    ],
$ y  _5 B3 U6 P+ k9 P: M, j    "blockhash" : "000000000000000488f18f7659acd85b2bd06a5ed2c4439eea74a8b968d16656",
- J* r. E6 b# l$ N  L! H& S' l    "confirmations" : 19,, t3 b) l* C2 H" E
    "time" : 1383235737,
- y  O. ^+ l5 T    "blocktime" : 1383235737
1 J3 q! t$ M2 l}# z7 L* T# ^2 X% [, B2 B
scriptPubKey位于”vout”[0]->”scriptPubKey”->”hex”,即: 76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac 。) I% v0 ?9 Y! _" P
签名使用ECDSA算法,对其,“空白交易”签名之,执行:
- u) E5 J4 B6 C2 \7 L/ H# z- G$ bbitcoind signrawtransaction \
! m" U6 H8 _0 d# a: }( }"010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000" \
2 e7 V2 e  C% w! I# [, m. p6 O'[{"txid":"296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156","vout":0,"scriptPubKey":"76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac"}]'
- T- w/ q6 S$ G# F输出:  \9 V6 D. g8 }- K8 ]  I# P
{# n7 o+ ~7 q' n5 o9 L6 r) t
    "hex" : "010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e29000000008c493046022100f9da4f53a6a4a8317f6e7e9cd9a7b76e0f5e95dcdf70f1b1e2b3548eaa3a6975022100858d48aed79da8873e09b0e41691f7f3e518ce9a88ea3d03f7b32eb818f6068801410477c075474b6798c6e2254d3d06c1ae3b91318ca5cc62d18398697208549f798e28efb6c55971a1de68cca81215dd53686c31ad8155cdc03563bf3f73ce87b4aaffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000",- U& L2 q" Y. F! a5 \/ C$ L
    "complete" : true
! X. _! o; b2 L7 }! n# ^}' F/ S' B  E% {  E. e4 e. }. q
签名后,签名值会填入上文所述的空字段中,从而得到一个完整的交易。可通过上文介绍的命令decoderawtransaction 解码查看之。) r8 u9 a1 H5 V0 V
最后一步,就是将其广播出去,等待网络传播至所有节点,约10~60秒广播至全球节点,取决与你的节点的网络连接状况。稍后一些时刻,就会进入Block中。广播由命令sendrawtransaction 来完成。如果没有运行节点,可以通过公共节点的API进行广播,例如:blockchain.info/pushtx。  e; j; ?. T: P  m+ e
执行:
5 j7 B/ H6 N; l- s) Tbitcoind sendrawtransaction \' V& y( F- E2 ~3 U  N% Y
"010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e29000000008c493046022100f9da4f53a6a4a8317f6e7e9cd9a7b76e0f5e95dcdf70f1b1e2b3548eaa3a6975022100858d48aed79da8873e09b0e41691f7f3e518ce9a88ea3d03f7b32eb818f6068801410477c075474b6798c6e2254d3d06c1ae3b91318ca5cc62d18398697208549f798e28efb6c55971a1de68cca81215dd53686c31ad8155cdc03563bf3f73ce87b4aaffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000"
8 Q. d: p% L6 F( w输出:# j$ h2 U) I# e- o
b5f8da1ea9e02ec3cc0765f9600f49945e94ed4b0c88ed0648896bf3e213205d
& `2 c! ]2 A9 I! Q1 D- G# b返回的是Transaction Hash值,即该交易的ID。至此,交易构造、签名、发送的完整过程完成了。
( F  T3 G5 t/ ^7 Z5 f2 G合成地址交易' \6 H% C" L/ e" U5 y/ n
合成地址以3开头,可以实现多方管理资产,极大提高安全性,也可以轻松实现基于比特币原生的三方交易担保支付。一个M-of-N的模式:7 F) Y1 y# l( O. s, g( `
m {pubkey}...{pubkey} n OP_CHECKMULTISIG
9 P6 c5 Y8 Q* s1 T7 g1 TM和N需满足:/ R. U' U# q% J4 v
1$ N+ p( x% H, h* G' R
1 of 3,最大程度私钥冗余。防丢私钥损失,3把私钥中任意一把即可签名发币,即使丢失2把都可以保障不受损失;
% B9 D+ T" E& o- G2 of 3,提高私钥冗余度的同时解决单点信任问题。3把私钥任意2把私钥可签名发币,三方不完全信任的情形,即中介交易中,非常适用;
, i6 v" a! C: K3 of 3,最大程度解决资金信任问题,无私钥冗余。必须3把私钥全部签名才能发币,适用多方共同管理重要资产,但任何一方遗失私钥均造成严重损失;
' r" [' D2 Y, h+ Z合成地址的交易构造、签名、发送过程与普通交易类似,这里只介绍如何创建一个合成地址。大神Gavin Andresen已经演示过,下面内容摘自其gist.2 x( U+ P. s) G5 J, R* ^- ?
首先,需要三对公钥、私钥。公钥创建地址、私钥用于签名。
9 P: d: _2 |" N5 q! C8 \  r# No.16 R" y/ q0 j4 `  R
0491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f86 / 5JaTXbAUmfPYZFRwrYaALK48fN6sFJp4rHqq2QSXs8ucfpE4yQU% D9 E- I$ E* o
# No.2
) i% D( `1 h. G& \04865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec6874 / 5Jb7fCeh1Wtm4yBBg3q3XbT6B525i17kVhy3vMC9AqfR6FH2qGk
% A) f0 _; V: u' i7 h" k8 J# No.3
/ N. C7 N- N# d/ x1 ?048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46213 / 5JFjmGo5Fww9p8gvx48qBYDJNAzR9pmH5S389axMtDyPT8ddqmw4 C$ Z! v) i6 t" V% U, C
使用命令:createmultisig  来合成,其中key为公钥,创建地址时仅需公钥。创建类型是2 of 3.
" Y) n& \% {0 a! h: S* o: Y( O- m输入:
- M" K7 w. P$ F& y$ R' M7 obitcoind createmultisig 2 \
2 L; ?: t7 i! z8 y7 N/ N'["0491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f86","04865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec6874","048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46213"]'# B2 w3 z1 i: q, i8 ?, f
输出:& I- j' ^' l' ~5 h5 i4 r" j7 f, P
{% n' Z  A) G7 h" a) n, H
    "address" : "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC",
! R0 p0 f7 ~6 X    "redeemScript" : "52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae"
- r  d$ ~5 G  ^; a}
1 L  }8 e: }- U; G' j得到的合成地址是:3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC,该地址没有公钥,仅有redeemScript,作用与公钥相同。后续的构造、签名、发送过程与上文普通地址交易类似,略去。
! h# s: x( V  C; z  h5 k) Q, p, g转自比特币实验室
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

梦的衣裳323 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    5