Next, you need to sign the hashOfBlobToSign using the private key of your account (ie. the “from” account). The details of doing so are outside the scope of this doc, but Radix follows a similar signature method as that of Bitcoin, using ECDSA signatures using EC curve “secp256k1”.
The result should be a DER encoded signature in hex that you will use in the following step.
The following python script will perform the signing operation and produce the correct hex formatted DER encoded signature that you can use to complete the transaction process:
import ecdsa
import hashlib
from ecdsa.curves import SECP256k1
from ecdsa.util import sigencode_der
private_key_hex = "YOUR_PRIVATE_KEY_AS_A_HEX_STRING"
hash_to_sign = "HASH_OF_BLOB_TO_SIGN"
# Create Private Key object from Private Key Hex String
signing_key = ecdsa.SigningKey.from_string(bytearray.fromhex(private_key_hex), curve=SECP256k1, hashfunc=hashlib.sha256)
# Use the Private Key to Sign the Transaction Hash
signed_hash = signing_key.sign_digest(bytearray.fromhex(hash_to_sign), sigencode=sigencode_der)
print("Signed Hash (DER Format): ", signed_hash.hex())
Note: You will need to change the YOUR_PRIVATE_KEY_AS_A_HEX_STRING and HASH_OF_BLOB_TO_SIGN variables
hey, really really stupid question maybe, but: how do I get my private key hex? I only have my node-config file with password protection how can i read the private key from that?.. I’m sorry if that question is stupid but i am a beginner. brgds and thx
Hi, if you have your node’s keystore.ks file then you can extract the private key using part of @Stuart’s unregister script and hex encode it as follows:
import bech32
import ecdsa
import hashlib
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography.hazmat.backends import default_backend
from ecdsa.curves import SECP256k1
from ecdsa.util import sigencode_der
import requests
import json
password = b"<KEYSTORE PASSWORD>"
# Read the Radix Keystore File (which is in PKCS12 format)
with open("node-keystore.ks", "rb") as f:
private_key, certificate, additional_certificates = pkcs12.load_key_and_certificates(f.read(), password, default_backend())
# Extract the unencrypted Private Key bytes
private_key_bytes = private_key.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())
# Convert into Elliptic Curve Digital Signature Algorithm (ecdsa) private key object
private_key = ecdsa.SigningKey.from_der(private_key_bytes, hashfunc=hashlib.sha256)
private_key_string = private_key.to_string()
print("Private Key (Hex): ", private_key_string.hex())
Next, you need to sign the payload_to_sign using the private key of your account (ie. the “from” account). The details of doing so are outside the scope of this doc, but Radix follows a similar signature method as that of Bitcoin, using ECDSA signatures using EC curve “secp256k1”. The result should be a DER encoded signature in hex that you will use in the following step.
I (obviously) know the 24 words, but how does that translate into the longstring needed?
Hi Peachy, I had the exact same problem and couldn’t figure it out so just created a development wallet using Stuart’s script here: Development Wallet Creation
This will allow you to create the necessary hex encoded keys to play around with txs using the API.
I believe 0xOmar in Discord has also created a python library that can extract the private key from the desktop wallet seed, so you could look into that if you want to use the desktop wallet created address.
I use construction/build to build a tx, it returned {"unsigned_transaction":"070d8ba1cbec4f2779517da61fb","payload_to_sign":"05a987eec4fa0ea073f5dc68b2689fa19bd03bd35f055da9370a1d5457279342"} ,
then I use construction/submit to send tx , { "network_identifier": { "network": "mainnet" }, "signed_transaction": "07030e70947..." }
by locally signed tx, How to construct the content signed_transaction of the field?
How the content of the transaction and the signature of the transaction are structured into one field
Once you have the unsigned_transaction blob, you need to finalise the transaction with this along with the signature. The signature is a hash of your private key and the payload_to_sign from the construction step. Here’s a python snippet for that part:
import ecdsa
import hashlib
from ecdsa.curves import SECP256k1
from ecdsa.util import sigencode_der
private_key_hex = "<enter private key here>"
hash_to_sign = "<enter payload to sign here>"
# Create Private Key object from Private Key Hex String
signing_key = ecdsa.SigningKey.from_string(bytearray.fromhex(private_key_hex), curve=SECP256k1, hashfunc=hashlib.sha256)
# Use the Private Key to Sign the Transaction Hash
signed_hash = signing_key.sign_digest(bytearray.fromhex(hash_to_sign), sigencode=sigencode_der)
print("Signed Hash (DER Format): ", signed_hash.hex())
Hello, I want to ask a silly thing, I have learned to sign in transactions using my main wallet, to make transactions, the problem is if I leak the contents of wallet.js to other people. can the contents of my wallet be drained by someone else, using this script?
And is wallet.js on radix wallet not securely protected? I can edit and move easily. will there be any improvements to make it securely encrypted so it’s not easy to find or steal.