Skip to content
Snippets Groups Projects
Commit 41f2b864 authored by Vincent Texier's avatar Vincent Texier
Browse files

[enh] #95 add signing_key argument in Document.__init__ and sub-classes

argument is Optional[SigningKey] with default=None
parent 3a49eca8
No related branches found
No related tags found
No related merge requests found
Pipeline #12876 passed
......@@ -176,10 +176,12 @@ class Block(Document):
transactions: List[Transaction],
inner_hash: str,
nonce: int,
signing_key: SigningKey = None,
) -> None:
"""
Constructor
:param signing_key:
:param version: duniter protocol version
:param currency: the block currency
:param number: the number of the block
......@@ -206,6 +208,7 @@ class Block(Document):
:param transactions: transactions documents
:param inner_hash: the block hash
:param nonce: the nonce value of the block
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
......@@ -247,6 +250,9 @@ class Block(Document):
self.inner_hash = inner_hash
self.nonce = nonce
if signing_key is not None:
self.sign(signing_key)
@property
def blockUID(self) -> BlockUID:
"""
......
......@@ -63,15 +63,18 @@ class Certification(Document):
pubkey_from: str,
identity: Union[Identity, str],
timestamp: BlockUID,
signing_key: SigningKey = None,
) -> None:
"""
Constructor
:param signing_key:
:param version: the UCP version
:param currency: the currency of the blockchain
:param pubkey_from: Pubkey of the certifier
:param identity: Document instance of the certified identity or identity pubkey string
:param timestamp: the blockuid
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
self.pubkey_from = pubkey_from
......@@ -79,6 +82,9 @@ class Certification(Document):
self.pubkey_to = identity.pubkey if isinstance(identity, Identity) else identity
self.timestamp = timestamp
if signing_key is not None:
self.sign(signing_key)
@classmethod
def from_signed_raw(
cls: Type[CertificationType], signed_raw: str
......
......@@ -55,17 +55,23 @@ class Document:
"Signature": re_signature,
}
def __init__(self, version: int, currency: str) -> None:
def __init__(
self, version: int, currency: str, signing_key: SigningKey = None
) -> None:
"""
Init Document instance
:param version: Version of the Document
:param currency: Name of the currency
:param signing_key: SigningKey instance to sign the document (default=None)
"""
self.version = version
self.currency = currency
self.signature: Optional[str] = None
if signing_key is not None:
self.sign(signing_key)
@classmethod
def parse_field(cls: Type[DocumentType], field_name: str, line: str) -> Any:
"""
......
......@@ -17,10 +17,12 @@ import re
from typing import Type, TypeVar
from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX, UID_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID
from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
IdentityType = TypeVar("IdentityType", bound="Identity")
......@@ -77,7 +79,13 @@ class Identity(Document):
}
def __init__(
self, version: int, currency: str, pubkey: str, uid: str, timestamp: BlockUID
self,
version: int,
currency: str,
pubkey: str,
uid: str,
timestamp: BlockUID,
signing_key: SigningKey = None,
) -> None:
"""
Create an identity document
......@@ -87,6 +95,7 @@ class Identity(Document):
:param pubkey: Public key of the account linked to the identity
:param uid: Unique identifier
:param timestamp: BlockUID instance
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
......@@ -94,6 +103,9 @@ class Identity(Document):
self.timestamp = timestamp
self.uid = uid
if signing_key is not None:
self.sign(signing_key)
@classmethod
def from_inline(
cls: Type[IdentityType], version: int, currency: str, inline: str
......
......@@ -17,10 +17,12 @@ import re
from typing import Type, TypeVar
from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID
from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
MembershipType = TypeVar("MembershipType", bound="Membership")
......@@ -82,6 +84,7 @@ class Membership(Document):
membership_type: str,
uid: str,
identity_ts: BlockUID,
signing_key: SigningKey = None,
) -> None:
"""
Create a membership document
......@@ -93,6 +96,7 @@ class Membership(Document):
:param membership_type: "IN" or "OUT" to enter or quit the community
:param uid: Unique identifier of the identity
:param identity_ts: BlockUID of the identity
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
......@@ -102,6 +106,9 @@ class Membership(Document):
self.uid = uid
self.identity_ts = identity_ts
if signing_key is not None:
self.sign(signing_key)
@classmethod
def from_inline(
cls: Type[MembershipType],
......
......@@ -19,10 +19,12 @@ from typing import List, Type, TypeVar
from duniterpy.api.endpoint import Endpoint, endpoint
from ..constants import BLOCK_HASH_REGEX, PUBKEY_REGEX
# required to type hint cls in classmethod
from ..key import SigningKey
from .block_uid import BlockUID
from .document import Document, MalformedDocumentError
# required to type hint cls in classmethod
PeerType = TypeVar("PeerType", bound="Peer")
......@@ -69,6 +71,7 @@ class Peer(Document):
pubkey: str,
block_uid: BlockUID,
endpoints: List[Endpoint],
signing_key: SigningKey = None,
) -> None:
"""
Init Peer instance
......@@ -78,6 +81,7 @@ class Peer(Document):
:param pubkey: Public key of the issuer
:param block_uid: BlockUID instance timestamp
:param endpoints: List of endpoints string
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
......@@ -85,6 +89,9 @@ class Peer(Document):
self.blockUID = block_uid
self.endpoints: List[Endpoint] = endpoints
if signing_key is not None:
self.sign(signing_key)
@classmethod
def from_signed_raw(cls: Type[PeerType], raw: str) -> PeerType:
"""
......
......@@ -61,7 +61,11 @@ class Revocation(Document):
}
def __init__(
self, version: int, currency: str, identity: Union[Identity, str]
self,
version: int,
currency: str,
identity: Union[Identity, str],
signing_key: SigningKey = None,
) -> None:
"""
Init Revocation instance
......@@ -69,12 +73,16 @@ class Revocation(Document):
:param version: Version number
:param currency: Name of the currency
:param identity: Identity instance or identity pubkey
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
self.identity = identity if isinstance(identity, Identity) else None
self.pubkey = identity.pubkey if isinstance(identity, Identity) else identity
if signing_key is not None:
self.sign(signing_key)
@classmethod
def from_inline(
cls: Type[RevocationType], version: int, currency: str, inline: str
......
......@@ -548,6 +548,7 @@ class Transaction(Document):
outputs: List[OutputSource],
comment: str,
time: Optional[int] = None,
signing_key: SigningKey = None,
) -> None:
"""
Init Transaction instance
......@@ -562,6 +563,7 @@ class Transaction(Document):
:param outputs: List of OutputSource instances
:param comment: Comment field
:param time: time when the transaction enters the blockchain
:param signing_key: SigningKey instance to sign the document (default=None)
"""
super().__init__(version, currency)
self.blockstamp = blockstamp
......@@ -574,6 +576,9 @@ class Transaction(Document):
self.time = time
self.signatures: List[str] = list()
if signing_key is not None:
self.sign(signing_key)
def __eq__(self, other: Any) -> bool:
"""
Check Transaction instances equality
......
......@@ -84,10 +84,9 @@ def get_signed_raw_revocation_document(
:rtype: str
"""
revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity)
key = SigningKey.from_credentials(salt, password)
revocation.sign(key)
revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity, key)
return revocation.signed_raw()
......@@ -122,7 +121,7 @@ def save_revoke_document():
# capture current block to get currency name
current_block = client(bma.blockchain.current)
# create our Identity document to sign the Certification document
# create our Identity document to sign the revocation document
identity = get_identity_document(client, current_block, pubkey)
if identity is None:
print("Identity not found for pubkey {0}".format(pubkey))
......
......@@ -57,14 +57,14 @@ def get_identity_document(
def get_certification_document(
current_block: dict, self_cert_document: Identity, from_pubkey: str
current_block: dict, identity: Identity, signing_key: SigningKey
) -> Certification:
"""
Create and return a Certification document
:param current_block: Current block data
:param self_cert_document: Identity document
:param from_pubkey: Pubkey of the certifier
:param identity: Identity document instance
:param signing_key: Signing key of the certifier
:rtype: Certification
"""
......@@ -72,9 +72,10 @@ def get_certification_document(
return Certification(
version=10,
currency=current_block["currency"],
pubkey_from=from_pubkey,
identity=self_cert_document,
pubkey_from=signing_key.pubkey,
identity=identity,
timestamp=BlockUID(current_block["number"], current_block["hash"]),
signing_key=signing_key,
)
......@@ -97,7 +98,6 @@ def send_certification():
# create key from credentials
key = SigningKey.from_credentials(salt, password)
pubkey_from = key.pubkey
# prompt entry
pubkey_to = input("Enter pubkey to certify: ")
......@@ -113,10 +113,7 @@ def send_certification():
return
# send the Certification document to the node
certification = get_certification_document(current_block, identity, pubkey_from)
# sign document
certification.sign([key])
certification = get_certification_document(current_block, identity, key)
# Here we request for the path wot/certify
try:
......
......@@ -57,11 +57,9 @@ def get_identity_document(
pubkey=key.pubkey,
uid=uid,
timestamp=timestamp,
signing_key=key,
)
# sign document
identity.sign(key)
return identity
......
......@@ -65,11 +65,9 @@ def get_membership_document(
membership_type=membership_type,
uid=uid,
identity_ts=identity_timestamp,
signing_key=key,
)
# sign document
membership.sign(key)
return membership
......
......@@ -42,7 +42,11 @@ TRANSACTION_VERSION = 10
def get_transaction_document(
current_block: dict, source: dict, from_pubkey: str, to_pubkey: str
current_block: dict,
source: dict,
from_pubkey: str,
to_pubkey: str,
signing_key: SigningKey,
) -> Transaction:
"""
Return a Transaction document
......@@ -51,6 +55,7 @@ def get_transaction_document(
:param source: Source to send
:param from_pubkey: Public key of the issuer
:param to_pubkey: Public key of the receiver
:param signing_key: Signing key of the issuer
:return: Transaction
"""
......@@ -97,6 +102,7 @@ def get_transaction_document(
unlocks=unlocks,
outputs=outputs,
comment="",
signing_key=signing_key,
)
return transaction
......@@ -141,12 +147,9 @@ def send_transaction():
# create the transaction document
transaction = get_transaction_document(
current_block, source, pubkey_from, pubkey_to
current_block, source, pubkey_from, pubkey_to, key
)
# sign document
transaction.sign([key])
# send the Transaction document to the node
try:
client(bma.tx.process, transaction.signed_raw())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment