def exec(self, script): op = script.split('\t') stack = [] for i in range(len(op)): ## print(stack) ## print(op[i]) ## print() if op[i] == 'OP_DUP': stack.append(stack[-1]) elif op[i] == 'OP_HASH160': #print(type(stack[-1])) stack[-1] = zsign.hash160(stack[-1]) #print('e:',stack[-1],'\n',stack[-2]) elif op[i] == 'OP_EQUALVERIFY': #print('e:',stack[-1],'\n',stack[-2]) if stack[-1] != stack[-2]: print('EQU!\n') return False del stack[-1] del stack[-1] elif op[i] == 'OP_CHECKSIG': if not (self.checksig(bytes(stack[-2], encoding='utf-8'), bytes(stack[-1], encoding='utf-8'))): print('SIG!\n') return False del stack[-1] del stack[-1] else: stack.append(op[i]) if len(stack) > 0: return False return True
def output_script_gen(self, output_public_key, script_type): if script_type == 'pay-to-script-hash': tmp = zsign.hash160(str(output_public_key, encoding='utf-8')) #print('sign key:',output_public_key,'\n',tmp,'\n') ans = 'OP_DUP\tOP_HASH160\t' + tmp + '\tOP_EQUALVERIFY\tOP_CHECKSIG' return ans
def exec(self, script): #执行验证脚本 op = script.split('\t') #脚本使用字符串形式存储,用\t分隔 stack = [] for i in range(len(op)): ## print(stack) ## print(op[i]) ## print() if op[i] == 'OP_DUP': #复制栈顶数据 stack.append(stack[-1]) elif op[i] == 'OP_HASH160': #对栈顶数据计算hash160并替换 #print(type(stack[-1])) stack[-1] = zsign.hash160(stack[-1]) #print('e:',stack[-1],'\n',stack[-2]) elif op[i] == 'OP_EQUALVERIFY': #判断栈顶处两个数据是否相等,并删除 #print('e:',stack[-1],'\n',stack[-2]) if stack[-1] != stack[-2]: print('EQU!\n') return False del stack[-1] del stack[-1] elif op[i] == 'OP_CHECKSIG': #用公钥stack[-1]判断签名stack[-2]是否正确 #公钥和前面要先转化为bytes类型 if not (self.checksig(bytes(stack[-2], encoding='utf-8'), bytes(stack[-1], encoding='utf-8'))): print('SIG!\n') return False del stack[-1] del stack[-1] elif op[i] == 'OP_CHECKMULTISIG': #验证多重签名 public_keys = [] sigs = [] original = 'OP_CHECKMULTISIG' #生成原始输出脚本 key_num = int(stack[-1]) #读取总签名个数N original = str(key_num) + '\t' + original del stack[-1] for j in range(key_num): #读入公钥 public_keys.append(bytes(stack[-1], encoding='utf-8')) original = stack[-1] + '\t' + original del stack[-1] sig_num = int(stack[-1]) #读取最少签名数M original = str(sig_num) + '\t' + original del stack[-1] for j in range(sig_num): #读入签名 sigs.append(bytes(stack[-1], encoding='utf-8')) del stack[-1] if not (self.checkmultisig(sig_num, key_num, sigs, public_keys)): #验证 print('MULTISIG!\n') return False stack.append(original) elif op[i] == 'OP_0': #占位符,无操作 continue else: #是操作数,直接进栈 stack.append(op[i]) if len(stack) > 0: #脚本不完整,验证失败 return False return True #验证成功
def output_script_gen(self, output_public_key, script_type, M=None, N=None): #生成输出的验证脚本,需要传入:接收方的公钥、脚本类型 if script_type == 'pay-to-public-key-hash': #p2sh tmp = zsign.hash160(str(output_public_key, encoding='utf-8')) #计算hash前将公钥转为str #print('sign key:',output_public_key,'\n',tmp,'\n') ans = 'OP_DUP\tOP_HASH160\t' + tmp + '\tOP_EQUALVERIFY\tOP_CHECKSIG' return ans if script_type == 'pay-to-public-key': #p2pk ans = str(output_public_key, encoding='utf-8') + '\tOP_CHECKSIG' return ans if script_type == 'pay-to-script-hash': #p2sh,此时公钥为列表 ans = '' ans = ans + str(M) + '\t' for i in range(N): #print(output_public_key) ans = ans + str(output_public_key[i], encoding='utf-8') + '\t' ans = ans + str(N) + '\tOP_CHECKMULTISIG' ans = 'OP_HASH160\t' + zsign.hash160(ans) + '\tOP_EQUALVERIFY' return ans
def calc_hash(self): #计算自身的hash值 #print('sha:',zsign.sha(zsign.to_str(self))) #print('to_str:',zsign.to_str(self),'\n') return zsign.hash160(zsign.to_str(self))