class CRCProposalReview(Payload): APPROVE = 0x00 REJECT = 0x01 ABSTAIN = 0x02 def __init__(self, private_key: str, proposal_hash: bytes, vote_result: int, opinion_hash: bytes): Payload.__init__(self, self.DEFAULT_VERSION) self.account = Account(private_key) self.proposal_hash = proposal_hash self.vote_result = vote_result self.opinion_hash = opinion_hash self.did = bytes.fromhex(self.account.did()) self.sign = None self.gen_signature() self.serialize_data = None def data(self, version: int): if self.serialize_data is not None: return self.serialize_data r = b"" r = self.serialize(r, self.version) self.serialize_data = r return r def serialize(self, r: bytes, version: int): r = self.serialize_unsigned(r, version) r = serialize.write_var_bytes(r, self.sign) return r def serialize_unsigned(self, r: bytes, version=0): r += self.proposal_hash r += struct.pack("<B", self.vote_result) r += self.opinion_hash r += self.did return r def deserialize(self, r: bytes, version: int): pass def gen_signature(self): r = b"" r = self.serialize_unsigned(r, self.version) self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r) return r def __repr__(self): return "CRCProposalReview {" + "\n\t" \ + "privateKey: {}".format(self.account.private_key()) + "\n\t" \ + "proposalHash: {}".format(self.proposal_hash.hex()) + "\n\t" \ + "voteResult : {}".format(self.vote_result) + "\n\t" \ + "crOpinionHash: {}".format(self.opinion_hash.hex()) + "\n\t" \ + "did : {}".format(keytool.create_address(self.did)) + "\n\t" \ + "sign: {}".format(self.sign.hex()) + "\n\t" \ + "}"
class CRCProposal(Payload): NORMAL = 0x0000 ELIP = 0x0100 FLOW_ELIP = 0x0101 INFO_ELIP = 0x0102 MAIN_CHAIN_UPGRADE_CODE = 0x0200 SIDE_CHAIN_UPGRADE_CODE = 0x0300 REGISTER_SIDE_CHAIN = 0x0301 SECRETARY_GENERAL = 0x0400 CHANGE_SPONSOR_OWNER = 0x0401 CLOSE_PROPOSAL = 0x0402 DAPP_CONSENSUS = 0x0500 WRONG = 0x4321 def __init__(self, private_key: str, cr_private_key: str, proposal_type: int, category_data: str, draft_hash: bytes, budget=None, recipient=None, target_proposal_hash=None, new_recipient=None, secretary_general_private_key=None, new_owner_private_key=None): Payload.__init__(self, self.DEFAULT_VERSION) self.account = Account(private_key) self.cr_account = Account(cr_private_key) self.secretary_general_account = None self.new_owner_account = None self.proposal_type = proposal_type self.category_data = category_data self.draft_hash = draft_hash self.target_proposal_hash = target_proposal_hash self.new_owner_public_key = None self.budget = budget self.recipient = recipient self.new_recipient = None self.secretary_general_public_key = None self.secretary_general_did = None self.sign = None self.new_owner_signature = None self.secretary_general_signature = None self._gen_secretary_general_account(secretary_general_private_key) self._gen_new_owner_account(new_owner_private_key) self.cr_council_member_did = bytes.fromhex(self.cr_account.did()) self.cr_council_member_sign = None self._gen_signature() self.hash = self.gen_hash() self.serialize_data = None def data(self, version: int): if self.serialize_data is not None: return self.serialize_data r = b"" r = self.serialize(r, self.version) self.serialize_data = r return r def serialize(self, r: bytes, version: int): if self.proposal_type is self.SECRETARY_GENERAL: return self.serialize_secretary_general(r, version) elif self.proposal_type is self.CHANGE_SPONSOR_OWNER: return self.serialize_change_proposal_owner(r, version) elif self.proposal_type is self.CLOSE_PROPOSAL: return self.serialize_close_proposal(r, version) else: return self.serialize_normal_or_elip(r, version) def serialize_normal_or_elip(self, r: bytes, version: int): r = self.serialize_unsigned_normal_or_elip(r, version) r = serialize.write_var_bytes(r, self.sign) r += self.cr_council_member_did r = serialize.write_var_bytes(r, self.cr_council_member_sign) return r def serialize_secretary_general(self, r: bytes, version: int): r = self.serialize_unsigned_secretary_genera(r, version) r = serialize.write_var_bytes(r, self.sign) r = serialize.write_var_bytes(r, self.secretary_general_signature) r += self.cr_council_member_did r = serialize.write_var_bytes(r, self.cr_council_member_sign) return r def serialize_change_proposal_owner(self, r: bytes, version: int): r = self.serialize_unsigned_change_proposal_owner(r, version) r = serialize.write_var_bytes(r, self.sign) r = serialize.write_var_bytes(r, self.new_owner_signature) r += self.cr_council_member_did r = serialize.write_var_bytes(r, self.cr_council_member_sign) return r def serialize_close_proposal(self, r: bytes, version: int): r = self.serialize_unsigned_close_proposal(r, version) r = serialize.write_var_bytes(r, self.sign) r += self.cr_council_member_did r = serialize.write_var_bytes(r, self.cr_council_member_sign) return r def serialize_unsigned_normal_or_elip(self, r: bytes, version=0): r += struct.pack("<H", self.proposal_type) r = serialize.write_var_bytes(r, bytes(self.category_data.encode())) r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key())) r += self.draft_hash r += serialize.write_var_uint(len(self.budget)) for budget in self.budget: r += budget.serialize(version) r += self.recipient return r def serialize_unsigned_secretary_genera(self, r: bytes, version=0): r += struct.pack("<H", self.proposal_type) r = serialize.write_var_bytes(r, bytes(self.category_data.encode())) r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key())) r += self.draft_hash r = serialize.write_var_bytes(r, self.secretary_general_public_key) r += self.secretary_general_did return r def serialize_unsigned_change_proposal_owner(self, r: bytes, version=0): r += struct.pack("<H", self.proposal_type) r = serialize.write_var_bytes(r, bytes(self.category_data.encode())) r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key())) r += self.draft_hash r += self.target_proposal_hash r += self.new_recipient r = serialize.write_var_bytes(r, self.new_owner_public_key) return r def serialize_unsigned_close_proposal(self, r: bytes, version=0): r += struct.pack("<H", self.proposal_type) r = serialize.write_var_bytes(r, bytes(self.category_data.encode())) r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key())) r += self.draft_hash r += self.target_proposal_hash return r def deserialize(self, r: bytes, version: int): pass def _gen_secretary_general_account(self, private_key): if private_key is not None: self.secretary_general_account = Account(private_key) self.secretary_general_public_key = bytes.fromhex(self.secretary_general_account.public_key()) self.secretary_general_did = bytes.fromhex(self.secretary_general_account.did()) def _gen_new_owner_account(self, private_key): if private_key is not None: self.new_owner_account = Account(private_key) self.new_owner_public_key = bytes.fromhex(self.new_owner_account.public_key()) self.new_recipient = bytes.fromhex(self.new_owner_account.did()) def get_deposit_address(self): return self.account.deposit_address() def _gen_signature(self): r = b"" if self.proposal_type is self.SECRETARY_GENERAL: r = self.serialize_unsigned_secretary_genera(r, self.version) self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r) self.secretary_general_signature = keytool.ecdsa_sign( bytes.fromhex(self.secretary_general_account.private_key()), r) r = serialize.write_var_bytes(r, self.sign) r = serialize.write_var_bytes(r, self.secretary_general_signature) r += self.cr_council_member_did self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r) return r elif self.proposal_type is self.CHANGE_SPONSOR_OWNER: r = self.serialize_unsigned_change_proposal_owner(r, self.version) self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r) self.new_owner_signature = keytool.ecdsa_sign(bytes.fromhex(self.new_owner_account.private_key()), r) r = serialize.write_var_bytes(r, self.sign) r = serialize.write_var_bytes(r, self.new_owner_signature) r += self.cr_council_member_did self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r) return r elif self.proposal_type is self.CLOSE_PROPOSAL: r = self.serialize_unsigned_close_proposal(r, self.version) self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r) r = serialize.write_var_bytes(r, self.sign) r += self.cr_council_member_did self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r) return r else: r = self.serialize_unsigned_normal_or_elip(r, self.version) self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r) r = serialize.write_var_bytes(r, self.sign) r += self.cr_council_member_did self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r) return r def gen_hash(self): r = b"" r = self.serialize(r, 0) return keytool.sha256_hash(r, 2) def __repr__(self): if self.proposal_type is self.SECRETARY_GENERAL: return "CRCProposalSecretaryGeneral {" + "\n\t" \ + "privateKey: {}".format(self.proposal_type) + "\n\t" \ + "crCouncilMemberDid: {}".format(self.proposal_type) + "\n\t" \ + "proposalType: {}".format(self.proposal_type) + "\n\t" \ + "categoryData : {}".format(self.category_data) + "\n\t" \ + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \ + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \ + "secretaryGeneralPublicKey: {}".format(self.secretary_general_public_key.hex()) + "\n\t" \ + "secretaryGeneralDid: {}".format(keytool.create_address(self.secretary_general_did)) + "\n\t" \ + "sign: {}".format(self.sign.hex()) + "\n\t" \ + "secretaryGeneralSignature: {}".format(self.secretary_general_signature.hex()) + "\n\t" \ + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \ + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \ + "hash: {}".format(self.hash.hex()) + "\n\t" \ + "}" elif self.proposal_type is self.CHANGE_SPONSOR_OWNER: return "CRCProposalChangeSponsor {" + "\n\t" \ + "proposalType: {}".format(self.proposal_type) + "\n\t" \ + "categoryData : {}".format(self.category_data) + "\n\t" \ + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \ + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \ + "targetProposalHash: {}".format(self.target_proposal_hash.hex()) + "\n\t" \ + "newRecipient: {}".format(keytool.create_address(self.new_recipient)) + "\n\t" \ + "newOwnerPublicKey: {}".format(self.new_owner_public_key.hex()) + "\n\t" \ + "sign: {}".format(self.sign.hex()) + "\n\t" \ + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \ + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \ + "hash: {}".format(self.hash.hex()) + "\n\t" \ + "}" elif self.proposal_type is self.CLOSE_PROPOSAL: return "CRCProposalCloseProposal {" + "\n\t" \ + "proposalType: {}".format(self.proposal_type) + "\n\t" \ + "categoryData : {}".format(self.category_data) + "\n\t" \ + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \ + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \ + "targetProposalHash: {}".format(self.target_proposal_hash.hex) + "\n\t" \ + "sign: {}".format(self.sign.hex()) + "\n\t" \ + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \ + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \ + "hash: {}".format(self.hash.hex()) + "\n\t" \ + "}" else: return "CRCProposal {" + "\n\t" \ + "proposalType: {}".format(self.proposal_type) + "\n\t" \ + "categoryData : {}".format(self.category_data) + "\n\t" \ + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \ + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \ + "budgets: {}".format(self.budget) + "\n\t" \ + "recipient: {}".format(keytool.create_address(self.recipient)) + "\n\t" \ + "sign: {}".format(self.sign.hex()) + "\n\t" \ + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \ + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \ + "hash: {}".format(self.hash.hex()) + "\n\t" \ + "}"
class CRInfo(Payload): CR_INFO_VERSION = 0x00 CR_INFO_DID_VERSION = 0x01 def __init__(self, private_key: str, nickname: str, url: str, location: int): Payload.__init__(self, self.DEFAULT_VERSION) self.account = Account(private_key) self.nickname = nickname self.url = url self.location = location self.code = self.account.redeem_script() self.cid = self.account.cid() self.did = self.account.did() self.signature = None self.gen_signature() self.serialize_data = None def data(self, version: int): if self.serialize_data is not None: return self.serialize_data r = b"" r = self.serialize(r, self.version) self.serialize_data = r return r def serialize(self, r: bytes, version: int): r = self.serialize_unsigned(r, version) if self.signature is not None: r = serialize.write_var_bytes(r, self.signature) return r def serialize_unsigned(self, r: bytes, version=0): r = serialize.write_var_bytes(r, bytes.fromhex(self.code)) r += bytes.fromhex(self.cid) r += bytes.fromhex(self.did) r = serialize.write_var_bytes(r, bytes(self.nickname.encode())) r = serialize.write_var_bytes(r, bytes(self.url.encode())) r += struct.pack("<Q", self.location) return r def deserialize(self, r: bytes, version: int): pass def get_deposit_address(self): return self.account.deposit_address() def gen_signature(self): r = b"" r = self.serialize_unsigned(r, self.version) signature = keytool.ecdsa_sign( bytes.fromhex(self.account.private_key()), r) self.signature = signature return signature def __repr__(self): return "CRInfo {" + "\n\t" \ + "privateKey: {}".format(self.account.private_key()) + "\n\t" \ + "code: {}".format(self.code) + "\n\t" \ + "cid : {}".format(keytool.create_address(bytes.fromhex(self.cid))) + "\n\t" \ + "did : {}".format(keytool.create_address(bytes.fromhex(self.did))) + "\n\t" \ + "nickname: {}".format(self.nickname) + "\n\t" \ + "url: {}".format(self.url) + "\n\t" \ + "location: {}".format(self.location) + "\n\t" \ + "signature: {}".format(self.signature.hex()) + "\n" \ + "}"