def sign(self, tx): """Sign a previously constructed transaction :type tx: Tx """ keys = self.keys_for_tx(tx) multisigcore.local_sign(tx, self.collect_redeem_scripts(tx), keys)
def make_partially_signed_tx(self): f = io.BytesIO(h2b( "01000000019cb9e92cd3f91087852382150f19b5d99259be47106d860055d1afb8110022250000000000ffffffff01d06c04000000000017a914f155ba65bdb30930da320ec51a0d6c913dfce06b8700000000e09304000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f27387")) unsigned = Tx.parse(f) unsigned.parse_unspents(f) script = self.account.script_for_path(TEST_PATH) child_key = self.wallet_private_key.subkey_for_path(TEST_PATH) local_sign(unsigned, [script], [child_key]) return unsigned
def make_partially_signed_tx(self): f = io.BytesIO( h2b("01000000019cb9e92cd3f91087852382150f19b5d99259be47106d860055d1afb8110022250000000000ffffffff01d06c04000000000017a914f155ba65bdb30930da320ec51a0d6c913dfce06b8700000000e09304000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f27387" )) unsigned = Tx.parse(f) unsigned.parse_unspents(f) script = self.account.script_for_path(TEST_PATH) child_key = self.wallet_private_key.subkey_for_path(TEST_PATH) local_sign(unsigned, [script], [child_key]) return unsigned
def make_partially_signed_tx_with_change(self): # generated with `tx -i 34DjTcNWGReJV4xx7R1AWK7FTz3xMwMcjA 3Ph5UGYHCyvYFQifw76T8iqKL9EkGKDBMz/90000 34DjTcNWGReJV4xx7R1AWK7FTz3xMwMcjA/200000 -o tx1.hex` # signing would be with `digital_oracle sign P:aaa-2015-02-10 P:bbb tx1.hex -i 0/0/1 -c - 0/0/1` f = io.BytesIO(h2b( "01000000019cb9e92cd3f91087852382150f19b5d99259be47106d860055d1afb8110022250000000000ffffffff02905f01000000000017a914f155ba65bdb30930da320ec51a0d6c913dfce06b87400d03000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f2738700000000e09304000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f27387")) unsigned = Tx.parse(f) unsigned.parse_unspents(f) script = self.account.script_for_path(TEST_PATH) child_key = self.wallet_private_key.subkey_for_path(TEST_PATH) local_sign(unsigned, [script], [child_key]) return unsigned
def make_partially_signed_tx_with_change(self): # generated with `tx -i 34DjTcNWGReJV4xx7R1AWK7FTz3xMwMcjA 3Ph5UGYHCyvYFQifw76T8iqKL9EkGKDBMz/90000 34DjTcNWGReJV4xx7R1AWK7FTz3xMwMcjA/200000 -o tx1.hex` # signing would be with `digital_oracle sign P:aaa-2015-02-10 P:bbb tx1.hex -i 0/0/1 -c - 0/0/1` f = io.BytesIO( h2b("01000000019cb9e92cd3f91087852382150f19b5d99259be47106d860055d1afb8110022250000000000ffffffff02905f01000000000017a914f155ba65bdb30930da320ec51a0d6c913dfce06b87400d03000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f2738700000000e09304000000000017a9141bbf6712630dd01fab4e70ac91a06925d138f27387" )) unsigned = Tx.parse(f) unsigned.parse_unspents(f) script = self.account.script_for_path(TEST_PATH) child_key = self.wallet_private_key.subkey_for_path(TEST_PATH) local_sign(unsigned, [script], [child_key]) return unsigned
def main(): parser = argparse.ArgumentParser( description='DigitalOracle HD multisig command line utility', formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-e', '--email', help='e-mail for create') parser.add_argument( '-p', '--phone', help='phone number for create - in the format +14155551212') parser.add_argument('-n', '--network', default='BTC', choices=NETWORK_NAMES) parser.add_argument('-i', "--inputpath", nargs='+', help='HD subkey path for each input (example: 0/2/15)') parser.add_argument( '-c', "--changepath", nargs='+', help= 'HD subkey path for each change output (example: 0/2/15) or a dash for non-change outputs' ) parser.add_argument( '-s', "--spendid", help= 'an additional hex string to disambiguate spends to the same address') parser.add_argument( '-u', "--baseurl", help= 'the API endpoint, defaults to the sandbox - https://s.digitaloracle.co/' ) parser.add_argument('-v', "--verbose", default=0, action="count", help="Verbosity, use more -v flags for more verbosity") parser.add_argument('command', help="""a command""") parser.add_argument('item', nargs='+', help="""a key""") parser.epilog = textwrap.dedent(""" Items: * P:wallet_passphrase - a secret for deriving an HD hierarchy with private keys * xpub - an account extended public key for deriving an HD hierarchy with public keys only * FILE.bin - unsigned transaction binary * FILE.hex - unsigned transaction hex Commands: * dump - dump the public subkeys * create - create Oracle account based on the supplied leading key with with any additional keys * address - get the deposit address for a subkey path * sign - sign a transaction, tx.bin or tx.hex must be supplied. Only one subkey path is supported. Notes: * --subkey is applicable for the address and sign actions, but not the create action """) args = parser.parse_args() keys = [] txs = [] for item in args.item: key = None tx = None if item.startswith('P:'): s = item[2:] key = BIP32Node.from_master_secret(s.encode('utf8'), netcode=args.network) keys.append(key) else: try: key = Key.from_text(item) keys.append(key) except encoding.EncodingError: pass if key is None: if os.path.exists(item): try: with open(item, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO( codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception as ex: print('could not parse %s %s' % (item, ex), file=sys.stderr) pass if tx is None and key is None: print('could not understand item %s' % (item, )) account = MultisigAccount(keys, complete=False) oracle = Oracle(account, tx_db=get_tx_db(), base_url=args.baseurl) oracle.verbose = args.verbose if args.command == 'dump': sub_keys = [ key.subkey_for_path(path or "") for key, path in izip_longest(keys, args.inputpath) ] for key in sub_keys: print(key.wallet_key(as_private=False)) elif args.command == 'create': calls = [] if args.email: calls.append('email') if args.phone: calls.append('phone') parameters = { "levels": [{ "asset": "BTC", "period": 60, "value": 0.001 }, { "delay": 0, "calls": calls }] } oracle.create(parameters, email=args.email, phone=args.phone) elif args.command == 'address': oracle.get() path = args.inputpath[0] if args.inputpath else "" payto = account.payto_for_path(path) if args.verbose > 0: sub_keys = [key.subkey_for_path(path) for key in account.keys] print("* account keys") print(account.keys) print("* child keys") for key in sub_keys: print(key.wallet_key(as_private=False)) print("* address") print(payto.address(netcode=args.network)) elif args.command == 'sign': oracle.get() scripts = [account.script_for_path(path) for path in args.inputpath] change_paths = [ None if path == '-' else path for path in (args.changepath or []) ] for tx in txs: print(tx.id()) print(b2h(stream_to_bytes(tx.stream))) sub_keys = [ keys[0].subkey_for_path(path) for path in args.inputpath ] # sign locally local_sign(tx, scripts, sub_keys) # have Oracle sign result = oracle.sign_with_paths(tx, args.inputpath, change_paths, spend_id=args.spendid) print("Result:") print(result) if 'transaction' in result: print("Hex serialized transaction:") print(b2h(stream_to_bytes(result['transaction'].stream))) else: print('unknown command %s' % (args.command, ), file=sys.stderr)
def main(): parser = argparse.ArgumentParser( description="DigitalOracle HD multisig command line utility", formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument("-e", "--email", help="e-mail for create") parser.add_argument("-p", "--phone", help="phone number for create - in the format +14155551212") parser.add_argument("-n", "--network", default="BTC", choices=NETWORK_NAMES) parser.add_argument("-i", "--inputpath", nargs="+", help="HD subkey path for each input (example: 0/2/15)") parser.add_argument( "-c", "--changepath", nargs="+", help="HD subkey path for each change output (example: 0/2/15) or a dash for non-change outputs", ) parser.add_argument("-s", "--spendid", help="an additional hex string to disambiguate spends to the same address") parser.add_argument( "-u", "--baseurl", help="the API endpoint, defaults to the sandbox - https://s.digitaloracle.co/" ) parser.add_argument( "-v", "--verbose", default=0, action="count", help="Verbosity, use more -v flags for more verbosity" ) parser.add_argument("command", help="""a command""") parser.add_argument("item", nargs="+", help="""a key""") parser.epilog = textwrap.dedent( """ Items: * P:wallet_passphrase - a secret for deriving an HD hierarchy with private keys * xpub - an account extended public key for deriving an HD hierarchy with public keys only * FILE.bin - unsigned transaction binary * FILE.hex - unsigned transaction hex Commands: * dump - dump the public subkeys * create - create Oracle account based on the supplied leading key with with any additional keys * address - get the deposit address for a subkey path * sign - sign a transaction, tx.bin or tx.hex must be supplied. Only one subkey path is supported. Notes: * --subkey is applicable for the address and sign actions, but not the create action """ ) args = parser.parse_args() keys = [] txs = [] for item in args.item: key = None tx = None if item.startswith("P:"): s = item[2:] key = BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network) keys.append(key) else: try: key = Key.from_text(item) keys.append(key) except encoding.EncodingError: pass if key is None: if os.path.exists(item): try: with open(item, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception as ex: print("could not parse %s %s" % (item, ex), file=sys.stderr) pass if tx is None and key is None: print("could not understand item %s" % (item,)) account = MultisigAccount(keys, complete=False) oracle = Oracle(account, tx_db=get_tx_db(), base_url=args.baseurl) oracle.verbose = args.verbose if args.command == "dump": sub_keys = [key.subkey_for_path(path or "") for key, path in izip_longest(keys, args.inputpath)] for key in sub_keys: print(key.wallet_key(as_private=False)) elif args.command == "create": calls = [] if args.email: calls.append("email") if args.phone: calls.append("phone") parameters = {"levels": [{"asset": "BTC", "period": 60, "value": 0.001}, {"delay": 0, "calls": calls}]} oracle.create(parameters, email=args.email, phone=args.phone) elif args.command == "address": oracle.get() path = args.inputpath[0] if args.inputpath else "" payto = account.payto_for_path(path) if args.verbose > 0: sub_keys = [key.subkey_for_path(path) for key in account.keys] print("* account keys") print(account.keys) print("* child keys") for key in sub_keys: print(key.wallet_key(as_private=False)) print("* address") print(payto.address(netcode=args.network)) elif args.command == "sign": oracle.get() scripts = [account.script_for_path(path) for path in args.inputpath] change_paths = [None if path == "-" else path for path in (args.changepath or [])] for tx in txs: print(tx.id()) print(b2h(stream_to_bytes(tx.stream))) sub_keys = [keys[0].subkey_for_path(path) for path in args.inputpath] # sign locally local_sign(tx, scripts, sub_keys) # have Oracle sign result = oracle.sign_with_paths(tx, args.inputpath, change_paths, spend_id=args.spendid) print("Result:") print(result) if "transaction" in result: print("Hex serialized transaction:") print(b2h(stream_to_bytes(result["transaction"].stream))) else: print("unknown command %s" % (args.command,), file=sys.stderr)