From ab3b0134b56ef4534e8ea239d512339cfe033b4a Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Tue, 14 Aug 2018 16:16:29 -0400 Subject: [PATCH] Purchase Transaction Type --- lbrynet/wallet/database.py | 4 +++- lbrynet/wallet/script.py | 31 +++++++++++++++++++++++++++++-- lbrynet/wallet/transaction.py | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lbrynet/wallet/database.py b/lbrynet/wallet/database.py index 85eab2480..41adb2740 100644 --- a/lbrynet/wallet/database.py +++ b/lbrynet/wallet/database.py @@ -21,7 +21,8 @@ class WalletDatabase(BaseDatabase): claim_name text, is_claim boolean not null default 0, is_update boolean not null default 0, - is_support boolean not null default 0 + is_support boolean not null default 0, + is_purchase boolean not null default 0 ); """ @@ -38,6 +39,7 @@ class WalletDatabase(BaseDatabase): 'is_claim': txo.script.is_claim_name, 'is_update': txo.script.is_update_claim, 'is_support': txo.script.is_support_claim, + 'is_purchase': txo.script.is_purchase_claim, }) if txo.script.is_claim_involved: row['claim_id'] = txo.claim_id diff --git a/lbrynet/wallet/script.py b/lbrynet/wallet/script.py index af4723df2..68beeb5fc 100644 --- a/lbrynet/wallet/script.py +++ b/lbrynet/wallet/script.py @@ -12,6 +12,7 @@ class OutputScript(BaseOutputScript): OP_CLAIM_NAME = 0xb5 OP_SUPPORT_CLAIM = 0xb6 OP_UPDATE_CLAIM = 0xb7 + OP_PURCHASE_CLAIM = 0xb8 CLAIM_NAME_OPCODES = ( OP_CLAIM_NAME, PUSH_SINGLE('claim_name'), PUSH_SINGLE('claim'), @@ -46,13 +47,25 @@ class OutputScript(BaseOutputScript): UPDATE_CLAIM_OPCODES + BaseOutputScript.PAY_SCRIPT_HASH.opcodes )) + PURCHASE_CLAIM_OPCODES = ( + OP_PURCHASE_CLAIM, PUSH_SINGLE('claim_id'), OP_2DROP + ) + PURCHASE_CLAIM_PUBKEY = Template('purchase_claim+pay_pubkey_hash', ( + PURCHASE_CLAIM_OPCODES + BaseOutputScript.PAY_PUBKEY_HASH.opcodes + )) + PURCHASE_CLAIM_SCRIPT = Template('purchase_claim+pay_script_hash', ( + PURCHASE_CLAIM_OPCODES + BaseOutputScript.PAY_SCRIPT_HASH.opcodes + )) + templates = BaseOutputScript.templates + [ CLAIM_NAME_PUBKEY, CLAIM_NAME_SCRIPT, SUPPORT_CLAIM_PUBKEY, SUPPORT_CLAIM_SCRIPT, UPDATE_CLAIM_PUBKEY, - UPDATE_CLAIM_SCRIPT + UPDATE_CLAIM_SCRIPT, + PURCHASE_CLAIM_PUBKEY, + PURCHASE_CLAIM_SCRIPT ] @classmethod @@ -63,6 +76,13 @@ class OutputScript(BaseOutputScript): 'pubkey_hash': pubkey_hash }) + @classmethod + def purchase_claim_pubkey_hash(cls, claim_id, pubkey_hash): + return cls(template=cls.PURCHASE_CLAIM_PUBKEY, values={ + 'claim_id': claim_id, + 'pubkey_hash': pubkey_hash + }) + @classmethod def pay_update_claim_pubkey_hash(cls, claim_name, claim_id, claim, pubkey_hash): return cls(template=cls.UPDATE_CLAIM_PUBKEY, values={ @@ -84,6 +104,13 @@ class OutputScript(BaseOutputScript): def is_support_claim(self): return self.template.name.startswith('support_claim+') + @property + def is_purchase_claim(self): + return self.template.name.startswith('purchase_claim+') + @property def is_claim_involved(self): - return self.is_claim_name or self.is_support_claim or self.is_update_claim + return any(( + self.is_claim_name, self.is_support_claim, + self.is_update_claim, self.is_purchase_claim + )) diff --git a/lbrynet/wallet/transaction.py b/lbrynet/wallet/transaction.py index 18aa8a2d2..23644400f 100644 --- a/lbrynet/wallet/transaction.py +++ b/lbrynet/wallet/transaction.py @@ -54,6 +54,11 @@ class Output(BaseOutput): claim_name.encode(), claim, pubkey_hash) return cls(amount, script) + @classmethod + def purchase_claim_pubkey_hash(cls, amount: int, claim_id: str, pubkey_hash: bytes) -> 'Output': + script = cls.script_class.purchase_claim_pubkey_hash(unhexlify(claim_id)[::-1], pubkey_hash) + return cls(amount, script) + @classmethod def pay_update_claim_pubkey_hash( cls, amount: int, claim_name: str, claim_id: str, claim: bytes, pubkey_hash: bytes) -> 'Output': @@ -76,6 +81,15 @@ class Transaction(BaseTransaction): ) return cls.create([], [claim_output], funding_accounts, change_account) + @classmethod + def purchase(cls, claim: Output, amount: int, merchant_address: bytes, + funding_accounts: List[Account], change_account: Account): + ledger = cls.ensure_all_have_same_ledger(funding_accounts, change_account) + claim_output = Output.purchase_claim_pubkey_hash( + amount, claim.claim_id, ledger.address_to_hash160(merchant_address) + ) + return cls.create([], [claim_output], funding_accounts, change_account) + @classmethod def update(cls, previous_claim: Output, meta: ClaimDict, amount: int, holding_address: bytes, funding_accounts: List[Account], change_account: Account):