From the end of my previous article,
What we need for getting a image link are
- image
- signature
To make a signature we need:
- image hash (digest) : to create this prefix and image are needed.
- private key
Functions we should need in SignedTransaction:
- sign() for making a signature
- deriveDigest() for creating data hash
- verify() for checking sig is valid. (optional)
However, as you see SignedTransaction class is fit to json data thus We should adjust some methods to make it appropriate for image data.
My plan was to make a new class derived from SignedTransaction class and adjust below methods(just little bit!):
- deriveDigest
- sign
- verify (optional)
Before I start, I changed original steem-python code as little as possible, so my code doesn't look clean. But I hope it helps someone to write better code. :)
Ok, let's get it started!🚀
First, we should make the class "signImage" having SignedTransaction as a parent class.
class SignImage(steembase.transactions.SignedTransaction):
def __init__(self, steemd_instance, *args, **kwargs):
self.steemd = steemd_instance
super(SignImage, self).__init__(*args, **kwargs)
...
I wanna get a signature passing a binary image to the sign method of signImage with wif(private key) as parameter.
The original SignedTransaction class stores the signature in its inner variable(signatures). so I didn't change it.
signedtx = SignImage(steemd_instance=self.s.commit.steemd, **tx.json())
with open(img, 'rb') as f:
img = f.read()
signedtx.sign(img, wifs)
# Get the signature
signedtx.json().get("signatures")
To get a image hash override method "deriveDigest". The original deriveDigest uses chain param to get hash data but we don't need it. (message parameter = binary image) prefix must be added to binary image.
@staticmethod
def deriveDigest(message): # chain=None
""" it was overriden and makes image hash and byte message with prefix.
:param message:
:return: digest(image_hash) and byte message
"""
# 1. convert prefix to byte type
prefix_ = 'ImageSigningChallenge'.encode('utf-8')
print(prefix_)
# 3. concat prefix and image
msg = prefix_ + compat_bytes(message)
print('msg: ', msg)
# 4. get image hash
digest = hashlib.sha256(msg).digest()
print('data hash: ', digest)
return digest, msg
The deriveDigest is called in the sign method. the sign method in the SignedTransaction uses the message(json data) stored when it is created but we will pass it explicitly as a parameter. The sign method only needs digest. (The verify method need digest and message both.)
def sign(self, message, wifkeys):
# wifkeys: List
# message: binary image
self.digest, _ = SignImage.deriveDigest(message)
...
That's all for overriding two methods.
Then write code for using it. TransactionBuilder class and dummy data is used for parameters to create SignImage instance. It actually doesn't used in the sign process. ( As I said before, I preserved most parts of the original code except methods for sign. )
# make TransactionBuilder instance with dummy data
tx = transactionbuilder.TransactionBuilder(
None,
steemd_instance=sw.s.commit.steemd,
wallet_instance=sw.s.commit.wallet,
no_broadcast=sw.s.commit.no_broadcast,
expiration=sw.s.commit.expiration)
# make "dummy" data and append it to tx
data = sw.wrap_data("./../data/test.txt")
test_d = operations.Comment(data)
tx.appendOps([test_d])
signedtx = utils_.SignImage(steemd_instance=self.s.commit.steemd, **tx.json())
wifs = [self.get_private_posting_key()]
signedtx.sign(img, wifs)
tx["signatures"].extend(signedtx.json().get("signatures"))
img_name = os.path.basename(img_path)
content = {"image": (img_name, img)}
end_point = "https://steemitimages.com"
url = "{}/{}/{}".format(end_point, self.account, tx["signatures"][0])
print("url: ", url)
I'll attach a github repository url soon !! :)
* One I concerned about is that I didn't find a test server for uploading images. Thus repeating uploading tests too much is not recommanded.
If you know the test server then plz give me a comment!! 😊😊
Also welcome your kind feedback about my english🤣 Thank you!
2021.07.26 - [D.S/Project] - 210726mon - How to get image links from steemitimages server ? #1