def build_otputs(self): outputs = [] outputs.append((TYPE_SCRIPT, ScriptOutput(self.contract.op_return), 0)) for a in self.contract.addresses: outputs.append((TYPE_ADDRESS, a, 546)) outputs.append((TYPE_ADDRESS, self.contract.address, self.total_value)) return outputs
def create_last_will(self, ): outputs = [(TYPE_SCRIPT, ScriptOutput(make_opreturn(self.contract.address.to_ui_string().encode('utf8'))),0), (TYPE_ADDRESS, self.refresh_address, self.value+190), (TYPE_ADDRESS, self.cold_address, 546), (TYPE_ADDRESS, self.inheritor_address, 546)] try: tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) id = tx.txid() except NotEnoughFunds: return self.show_critical(_("Not enough balance to fund smart contract.")) except Exception as e: return self.show_critical(repr(e)) # preparing transaction, contract can't give a change self.main_window.network.broadcast_transaction2(tx) self.create_button.setText("Creating Last Will...") self.create_button.setDisabled(True) coin = self.wait_for_coin(id,10) self.wallet.add_input_info(coin) inputs = [coin] outputs = [(TYPE_ADDRESS, self.contract.address, self.value)] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version=2 show_transaction(tx, self.main_window, "Make Last Will contract", prompt_if_unsaved=True) if self.notification.do_anything() : outputs = self.notification.notification_outputs(self.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name, None, None)
def build_otputs(self): outputs = [] # convention used everywhere else in this plugin is is 0 for protege and 1 for mecenas # but I did it upside down here by mistake outputs.append((TYPE_SCRIPT, ScriptOutput(self.contract.op_return), 0)) for a in self.addresses: outputs.append((TYPE_ADDRESS, a, 546)) outputs.append((TYPE_ADDRESS, self.contract.address, self.total_value)) return outputs
def showscript(self,): if not self.contract: return script = self.contract.redeemscript schex = script.hex() try: sco = ScriptOutput(script) decompiled = sco.to_ui_string() except: decompiled = "decompiling error" d = QDialog(self) d.setWindowTitle(_('Split contract script')) d.setMinimumSize(610, 490) layout = QGridLayout(d) script_bytes_e = QTextEdit() layout.addWidget(QLabel(_('Bytes')), 1, 0) layout.addWidget(script_bytes_e, 1, 1) script_bytes_e.setText(schex) script_bytes_e.setReadOnly(True) #layout.setRowStretch(2,3) decompiled_e = QTextEdit() layout.addWidget(QLabel(_('ASM')), 3, 0) layout.addWidget(decompiled_e, 3, 1) decompiled_e.setText(decompiled) decompiled_e.setReadOnly(True) #layout.setRowStretch(3,1) hbox = QHBoxLayout() b = QPushButton(_("Close")) b.clicked.connect(d.accept) hbox.addWidget(b) layout.addLayout(hbox, 4, 1) # d.setWindowModality(Qt.WindowModal) # d.exec_() d.show()
def create_last_will(self, ): yorn = self.main_window.question( _("Do you wish to create the Last Will Contract?")) if not yorn: return data1 = self.contract.address.to_ui_string() + ' ' + str( self.contract.version) data2 = str(self.contract.i_time) + ' ' + str(self.contract.rl_time) op_return = joinbytes([ OpCodes.OP_RETURN, 4, b'>sh\x00', len(data1), data1.encode('utf8'), len(data2), data2.encode('utf8') ]) assert len(data1) < 76 and len(data2) < 76 print(op_return) outputs = [(TYPE_SCRIPT, ScriptOutput(op_return), 0), (TYPE_ADDRESS, self.refresh_address, 546), (TYPE_ADDRESS, self.cold_address, 546), (TYPE_ADDRESS, self.inheritor_address, 546), (TYPE_ADDRESS, self.contract.address, self.value)] try: tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) id = tx.txid() except NotEnoughFunds: return self.show_critical( _("Not enough balance to fund smart contract.")) except Exception as e: return self.show_critical(repr(e)) tx.version = 2 try: self.main_window.network.broadcast_transaction2(tx) except: pass self.create_button.setText("Creating Last Will...") self.create_button.setDisabled(True) if self.notification.do_anything(): outputs = self.notification.notification_outputs( self.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name, None, None)
def test_opreturns(self): try: with open(scripttests_local) as f: testlist = json.load(f) print("Got script tests from %s; will not download." % (scripttests_local, )) except IOError: print("Couldn't get script tests from %s; downloading from %s..." % (scripttests_local, scripttests_url)) testlist = requests.get(scripttests_url).json() print("Starting %d tests on SLP's OP_RETURN parser" % len(testlist)) for d in testlist: description = d['msg'] scripthex = d['script'] code = d['code'] if scripthex is None: continue if hasattr(code, '__iter__'): expected_codes = tuple(code) else: expected_codes = (code, ) with self.subTest(description=description, script=scripthex): sco = ScriptOutput(bytes.fromhex(scripthex)) try: msg = slp.SlpMessage.parseSlpOutputScript(sco) except Exception as e: if isinstance(e, slp.SlpInvalidOutputMessage): emsg = e.args if errorcodes[emsg] not in expected_codes: raise AssertionError( "Invalidity reason %r (code: %d) not in expected reasons %r" % (emsg, errorcodes[emsg], expected_codes)) elif isinstance(e, slp.SlpUnsupportedSlpTokenType): if 255 not in expected_codes: raise AssertionError( "SlpUnsupportedSlpTokenType exception raised (code 255) but not in expected reasons (%r)" % (expected_codes, )) else: raise else: # no exception if None not in expected_codes: raise AssertionError( "Script was found valid but should have been invalid, for a reason code in %r." % (expected_codes, )) pass
def tx_from_components(all_components, session_hash): """ Returns the tx and a list of indices matching inputs with components""" input_indices = [] assert len(session_hash) == 32 if Protocol.FUSE_ID is None: prefix = [] else: assert len(Protocol.FUSE_ID) == 4 prefix = [4, *Protocol.FUSE_ID] inputs = [] outputs = [ (TYPE_SCRIPT, ScriptOutput(bytes([OpCodes.OP_RETURN, *prefix, 32]) + session_hash), 0) ] for i, compser in enumerate(all_components): comp = pb.Component() comp.ParseFromString(compser) ctype = comp.WhichOneof('component') if ctype == 'input': inp = comp.input if len(inp.prev_txid) != 32: raise FusionError("bad component prevout") inputs.append( dict(address=Address.from_P2PKH_hash(hash160(inp.pubkey)), prevout_hash=inp.prev_txid[::-1].hex(), prevout_n=inp.prev_index, num_sig=1, signatures=[None], type='p2pkh', x_pubkeys=[inp.pubkey.hex()], pubkeys=[inp.pubkey.hex()], sequence=0xffffffff, value=inp.amount)) input_indices.append(i) elif ctype == 'output': out = comp.output atype, addr = get_address_from_output_script(out.scriptpubkey) if atype != TYPE_ADDRESS: raise FusionError("bad component address") outputs.append((TYPE_ADDRESS, addr, out.amount)) elif ctype != 'blank': raise FusionError("bad component") tx = Transaction.from_io(inputs, outputs, locktime=0, sign_schnorr=True) tx.version = 1 return tx, input_indices
def notification_outputs(self,contract_address): if not self.disabled: outputs = [] fee = 0 str = random.choice(string.ascii_letters+ string.punctuation + string.digits)+'\'' # salt if self.notify_me.isChecked(): str += self.my_email.text()+'\'' fee += self.nottify_me_fee if self.notify_inheritor.isChecked(): str += self.i_email.text() + '\'' +contract_address.to_ui_string() fee += self.nottify_inheritor_fee message = base64.b64decode(encrypt_message(str.encode('utf8'),self.licho_pubkey))[4:] print(message) outputs.append((TYPE_ADDRESS, self.licho_address, fee)) outputs.append( (TYPE_SCRIPT, ScriptOutput(make_opreturn(message)), 0) ) return outputs
def parse_output(self, x): try: address = self.parse_address(x) return bitcoin.TYPE_ADDRESS, address except: return bitcoin.TYPE_SCRIPT, ScriptOutput.from_string(x)
def parse_output(self, x): try: return bitcoin.TYPE_ADDRESS, Address.from_string(x) except: return bitcoin.TYPE_SCRIPT, ScriptOutput.from_string(x)