比特币全节点Go语言实现BTCD之脚本

释放双眼,带上耳机,听听看~!

比特币使用脚本系统来处理交易。脚本有着类Forth语言、简单、基于堆栈以及从左向右处理的特点。脚本故意限定为非图灵完备的,没有循环计算功能。

比特币中脚本最常用的是pubkeyhash脚本,即大家常说的P2PKH交易,还有一些其他的交易。如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1func typeOfScript(pops []parsedOpcode) ScriptClass {
2   if isPubkey(pops) {
3      return PubKeyTy
4} else if isPubkeyHash(pops) {
5      return PubKeyHashTy
6} else if isWitnessPubKeyHash(pops) {
7      return WitnessV0PubKeyHashTy
8} else if isScriptHash(pops) {
9      return ScriptHashTy
10} else if isWitnessScriptHash(pops) {
11      return WitnessV0ScriptHashTy
12} else if isMultiSig(pops) {
13      return MultiSigTy
14} else if isNullData(pops) {
15      return NullDataTy
16}
17   return NonStandardTy
18}
19

各种脚本验证方法,如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
1// isPubkey returns true if the script passed is a pay-to-pubkey transaction,
2// false otherwise.
3func isPubkey(pops []parsedOpcode) bool {
4   // Valid pubkeys are either 33 or 65 bytes.
5   return len(pops) == 2 &&
6      (len(pops[0].data) == 33 || len(pops[0].data) == 65) &&
7      pops[1].opcode.value == OP_CHECKSIG
8}
9
10// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash
11// transaction, false otherwise.
12func isPubkeyHash(pops []parsedOpcode) bool {
13   return len(pops) == 5 &&
14      pops[0].opcode.value == OP_DUP &&
15      pops[1].opcode.value == OP_HASH160 &&
16      pops[2].opcode.value == OP_DATA_20 &&
17      pops[3].opcode.value == OP_EQUALVERIFY &&
18      pops[4].opcode.value == OP_CHECKSIG
19}
20
21// isMultiSig returns true if the passed script is a multisig transaction, false
22// otherwise.
23func isMultiSig(pops []parsedOpcode) bool {
24   // The absolute minimum is 1 pubkey:
25   // OP_0/OP_1-16 <pubkey> OP_1 OP_CHECKMULTISIG
26   l := len(pops)
27   if l < 4 {
28      return false
29}
30   if !isSmallInt(pops[0].opcode) {
31      return false
32}
33   if !isSmallInt(pops[l-2].opcode) {
34      return false
35}
36   if pops[l-1].opcode.value != OP_CHECKMULTISIG {
37      return false
38}
39
40   // Verify the number of pubkeys specified matches the actual number
41   // of pubkeys provided.
42   if l-2-1 != asSmallInt(pops[l-2].opcode) {
43      return false
44}
45
46   for _, pop := range pops[1 : l-2] {
47      // Valid pubkeys are either 33 or 65 bytes.
48      if len(pop.data) != 33 && len(pop.data) != 65 {
49         return false
50}
51   }
52   return true
53}
54

1
2
1txscript/opcode.go文件包含所有的指令,是不包含循环指令的。  
2

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C/C++内存泄漏及检测

2022-1-11 12:36:11

安全工具

基于Alpine系统构建dnsmasq的docker镜像

2018-6-29 15:53:40

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索