def prepare_targets(self, etx_spec, their): self.targets = [] for address, color_spec, value in etx_spec.targets: colordef = self.ewctrl.resolve_color_spec(color_spec) self.targets.append(ColorTarget(address, SimpleColorValue(colordef=colordef, value=value))) wam = self.model.get_address_manager() colormap = self.model.get_color_map() their_colordef = self.ewctrl.resolve_color_spec(their['color_spec']) their_color_set = ColorSet.from_color_ids(self.model.get_color_map(), [their_colordef.get_color_id()]) ct = ColorTarget(wam.get_change_address(their_color_set).get_address(), SimpleColorValue(colordef=their_colordef, value=their['value'])) self.targets.append(ct)
def issue_coins(self, moniker, pck, units, atoms_in_unit): """Issues a new color of name <moniker> using coloring scheme <pck> with <units> per share and <atoms_in_unit> total. """ color_definition_cls = ColorDefinition.get_color_def_cls_for_code(pck) if not color_definition_cls: raise InvalidColorDefinitionError( 'color scheme %s not recognized' % pck) total = units * atoms_in_unit op_tx_spec = SimpleOperationalTxSpec(self.model, None) wam = self.model.get_address_manager() address = wam.get_new_genesis_address() colorvalue = SimpleColorValue(colordef=GENESIS_OUTPUT_MARKER, value=total) color_target = ColorTarget(address.get_address(), colorvalue) op_tx_spec.add_target(color_target) genesis_ctxs = color_definition_cls.compose_genesis_tx_spec(op_tx_spec) genesis_tx = self.model.transform_tx_spec(genesis_ctxs, 'signed') height = self.model.ccc.blockchain_state.bitcoind.getblockcount() \ - 1 genesis_tx_hash = self.publish_tx(genesis_tx) color_desc = ':'.join([pck, genesis_tx_hash, '0', str(height)]) adm = self.model.get_asset_definition_manager() asset = adm.add_asset_definition({ "monikers": [moniker], "color_set": [color_desc], "unit": atoms_in_unit }) wam.update_genesis_address(address, asset.get_color_set()) # scan the tx so that the rest of the system knows self.model.ccc.colordata.cdbuilder_manager.scan_txhash( asset.color_set.color_id_set, genesis_tx_hash)
def make_etx_spec(self, our, their): fee = FEE if our.get_colordef() == UNCOLORED_MARKER else 0 c_utxos, c_change = self.select_inputs(our + fee) inputs = { our.get_colordef(): [utxo.get_outpoint() for utxo in c_utxos] } wam = self.model.get_address_manager() our_color_set = ColorSet.from_color_ids(self.model.get_color_map(), [our.get_color_id()]) their_color_set = ColorSet.from_color_ids(self.model.get_color_map(), [their.get_color_id()]) our_address = wam.get_change_address(their_color_set) targets = [ColorTarget(our_address.get_address(), their)] if c_change > 0: our_change_address = wam.get_change_address(our_color_set) targets.append( ColorTarget(our_change_address.get_address(), c_change)) return ETxSpec(inputs, targets, c_utxos)
def prepare_targets(self, etx_spec, their): self.targets = etx_spec.targets wam = self.model.get_address_manager() colormap = self.model.get_color_map() their_color_set = ColorSet.from_color_ids(self.model.get_color_map(), [their.get_color_id()]) ct = ColorTarget( wam.get_change_address(their_color_set).get_address(), their) self.targets.append(ct)
def test_operational(self): self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) op = self.transformer.transform_basic(self.basic, 'operational') self.assertTrue(self.transformer.classify_tx_spec(op), 'operational') self.assertRaises(InvalidTargetError, op.add_target, 1) self.assertEqual(ColorTarget.sum(op.get_targets()), ColorTarget.sum(self.targets)) self.assertEqual(op.get_change_addr(self.colordef0), self.addr0) self.assertEqual(op.get_change_addr(UNCOLORED_MARKER), self.baddr) self.assertEqual(op.get_required_fee(1).get_value(), 10000) self.assertRaises(InvalidColorIdError, op.get_change_addr, self.colordef1) cv = SimpleColorValue(colordef=self.colordef0, value=0) self.assertRaises(ZeroSelectError, op.select_coins, cv) cv = SimpleColorValue(colordef=self.colordef0, value=5) self.assertRaises(InsufficientFundsError, op.select_coins, cv) self.add_coins() self.assertEqual(op.select_coins(cv)[1].get_value(), 100)
def sendmany_coins(self, entries): """Sendmany coins given in entries [(asset, address, value), ...] """ self.validate_sendmany_entries(entries) tx_spec = SimpleOperationalTxSpec(self.model, None) for asset, address, value in entries: color_id = asset.get_color_id() colordef = self.model.get_color_def(color_id) colorvalue = SimpleColorValue(colordef=colordef, value=value) tx_spec.add_target(ColorTarget(address, colorvalue)) signed_tx_spec = self.model.transform_tx_spec(tx_spec, 'signed') txhash = self.publish_tx(signed_tx_spec) # TODO add to history return txhash
def make_operational_tx_spec(self, asset): """Given a <tx_spec> of type BasicTxSpec, return a SimpleOperationalTxSpec. """ if not self.is_monocolor(): raise InvalidTransformationError('tx spec type not supported') op_tx_spec = SimpleOperationalTxSpec(self.model, asset) color_id = list(asset.get_color_set().color_id_set)[0] color_def = self.model.get_color_def(color_id) for target in self.targets: colorvalue = SimpleColorValue(colordef=color_def, value=target.get_value()) colortarget = ColorTarget(target.get_address(), colorvalue) op_tx_spec.add_target(colortarget) return op_tx_spec
def compose_uncolored_tx(tx_spec): """ compose a simple bitcoin transaction """ targets = tx_spec.get_targets() ttotal = ColorTarget.sum(targets) fee = tx_spec.get_required_fee(500) sel_utxos, sum_sel_coins = tx_spec.select_coins(ttotal + fee) change = sum_sel_coins - ttotal - fee txouts = [ComposedTxSpec.TxOut(target.get_satoshi(), target.get_address()) for target in targets] # give ourselves the change if change > 0: change_addr = tx_spec.get_change_addr(UNCOLORED_MARKER) txouts.append( ComposedTxSpec.TxOut(change.get_satoshi(), change_addr)) return ComposedTxSpec(sel_utxos, txouts)
def compose_uncolored_tx(tx_spec): """ compose a simple bitcoin transaction """ composed_tx_spec = tx_spec.make_composed_tx_spec() targets = tx_spec.get_targets() composed_tx_spec.add_txouts(targets) ttotal = ColorTarget.sum(targets) sel_utxos, sum_sel_coins = tx_spec.select_coins(ttotal, composed_tx_spec) composed_tx_spec.add_txins(sel_utxos) fee = composed_tx_spec.estimate_required_fee() change = sum_sel_coins - ttotal - fee # give ourselves the change if change > tx_spec.get_dust_threshold(): composed_tx_spec.add_txout(value=change, target_addr=tx_spec.get_change_addr(UNCOLORED_MARKER), is_fee_change=True) return composed_tx_spec
def setUp(self): self.path = ":memory:" self.pwallet = PersistentWallet(self.path) self.config = { 'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path': self.path }, 'bip0032': False } self.pwallet.wallet_config = self.config self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.colordesc0 = "obc:color0:0:0" self.colordesc1 = "obc:color1:0:0" self.colordesc2 = "obc:color2:0:0" # add some colordescs self.colorid0 = self.colormap.resolve_color_desc(self.colordesc0) self.colorid1 = self.colormap.resolve_color_desc(self.colordesc1) self.colorid2 = self.colormap.resolve_color_desc(self.colordesc2) self.colordef0 = OBColorDefinition(self.colorid0, { 'txhash': 'color0', 'outindex': 0 }) self.colordef1 = OBColorDefinition(self.colorid1, { 'txhash': 'color1', 'outindex': 0 }) self.colordef2 = OBColorDefinition(self.colorid2, { 'txhash': 'color2', 'outindex': 0 }) self.asset_config = { 'monikers': ['blue'], 'color_set': [self.colordesc0], } self.basset_config = { 'monikers': ['bitcoin'], 'color_set': [''], } self.asset = AssetDefinition(self.colormap, self.asset_config) self.basset = AssetDefinition(self.colormap, self.basset_config) self.basic = BasicTxSpec(self.model) self.bbasic = BasicTxSpec(self.model) wam = self.model.get_address_manager() self.address0 = wam.get_new_address(self.asset.get_color_set()) self.addr0 = self.address0.get_address() self.bcolorset = ColorSet(self.colormap, ['']) self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.assetvalue0 = AdditiveAssetValue(asset=self.asset, value=5) self.assetvalue1 = AdditiveAssetValue(asset=self.asset, value=6) self.assetvalue2 = AdditiveAssetValue(asset=self.asset, value=7) self.bassetvalue = AdditiveAssetValue(asset=self.basset, value=8) self.assettarget0 = AssetTarget(self.addr0, self.assetvalue0) self.assettarget1 = AssetTarget(self.addr0, self.assetvalue1) self.assettarget2 = AssetTarget(self.addr0, self.assetvalue2) self.bassettarget = AssetTarget(self.baddr, self.bassetvalue) self.atargets = [ self.assettarget0, self.assettarget1, self.assettarget2 ] # add some targets self.colorvalue0 = SimpleColorValue(colordef=self.colordef0, value=5) self.colortarget0 = ColorTarget(self.addr0, self.colorvalue0) self.colorvalue1 = SimpleColorValue(colordef=self.colordef0, value=6) self.colortarget1 = ColorTarget(self.addr0, self.colorvalue1) self.colorvalue2 = SimpleColorValue(colordef=self.colordef0, value=7) self.colortarget2 = ColorTarget(self.addr0, self.colorvalue2) self.bcolorvalue = SimpleColorValue(colordef=UNCOLORED_MARKER, value=8) self.bcolortarget = ColorTarget(self.baddr, self.bcolorvalue) self.targets = [ self.colortarget0, self.colortarget1, self.colortarget2 ] self.transformer = TransactionSpecTransformer(self.model, self.config) self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7'